我试图实现一个搜索栏,但我没有运气处理这个问题。我真的很感激可以提供任何帮助。我有一个大项目,我有一个表视图,我想在它上面实现一个搜索栏,看看实时过滤。我不使用Storyboard但我使用的是XIB。我添加了以下协议:
<UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UISearchDisplayDelegate>
我在@interface中声明了2个数组,第一个用于整个元素,第二个用于过滤的数组:
NSArray* OldList;
NSArray* filteredList;
然后我设置了行数和节数,然后:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
myClassCell *cell = [tableView dequeueReusableCellWithIdentifier:MYCELLCLASS];
if (cell == nil)
{
cell = [myClassCell newFromNib];
}
NSMutableDictionary* elem = nil;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
elem = [filteredList objectAtIndex:indexPath.row];
if ([elem count]+1 > indexPath.row)
[cell showValues:elem];
else
[cell showValues:nil];
}
else
{
elem = [OldList objectAtIndex:indexPath.row];
if ([elem count]+1 > indexPath.row)
[cell showValues:elem];
else
[cell showValues:nil];
}
return cell;
}
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];
filteredist = [OldList filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
return YES;
}
此时,我没有对xib进行任何更改,没有链接,也没有其他任何内容。如果我编译我得到我的表,但显然如果我尝试搜索某些东西,没有任何作用。此外,如果我向下滚动到表的末尾,应用程序崩溃。真正的问题是我无法看到搜索栏正常工作。有人可以帮帮我吗?
答案 0 :(得分:19)
嗯,你正确地走上正轨......这与你的控制器类与你的控制器xib的连接完全一致。
当您想要将搜索栏和搜索显示控制器初始化为UITableView时,您实际上是在添加第二个表视图,该视图在激活后必须由UITableViewController
类中的代码以与以下相同的方式进行管理:任何UITableView
。
我已经使用这些SO问题/答案来检查我自己的答案 - 我建议你看看:
我已阅读Apple Documentation。我建议你这样做,以帮助你理解这一点。
运行控制器类时,需要为两个表视图设置数据源和委托方法。
在执行此操作之前,请包含此属性...
@property (nonatomic, strong) UISearchDisplayController *searchController;
以下代码介绍了如何初始化和设置UISearchBar
和UISearchDisplayController
的相应属性。如果您以编程方式在代码中创建UITableViewController
,则还需要为其设置数据源和委托(未显示以使代码易于阅读)。
您有两个选择 - 您选择哪一个取决于您的代码和您希望实现的目标 - 您可以在init
/ awakeFromNib
方法中设置这些选项,或者在您的某个表格中设置这些选项视图控制器(TVC)生命周期方法。
选项一 - 初始
(注1:Paul Hegarty的非凡iTunesU讲座教会我按照以下方式启动/唤醒课程 - 通过这种方式,您可以使用这两种方案 - 您可以调用init或者它可以唤醒.FromNib。)
- (void)setup {
// Provide initialisation code here!!!
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
[searchBar sizeToFit];
[searchBar setDelegate:self];
[self setSearchController:[[UISearchDisplayController alloc] initWithSearchBar:searchBar
contentsController:self]];
[self.searchController setSearchResultsDataSource:self];
[self.searchController setSearchResultsDelegate:self];
[self.searchController setDelegate:self];
}
- (void)awakeFromNib {
[self setup];
}
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
[self setup];
}
return self;
}
或强>
选项二 - TVC生命周期
- (void)viewDidLoad {
[super viewDidLoad];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
[searchBar sizeToFit];
[searchBar setDelegate:self];
[self setSearchController:[[UISearchDisplayController alloc] initWithSearchBar:searchBar
contentsController:self]];
[self.searchController setSearchResultsDataSource:self];
[self.searchController setSearchResultsDelegate:self];
[self.searchController setDelegate:self];
[self.tableView setTableHeaderView:self.searchController.searchBar]; // see Note2
...< other code as required >...
}
注意2:无论您选择哪种选项,都需要在viewDidLoad
方法中放置以下代码行...
[self.tableView setTableHeaderView:self.searchController.searchBar]; // (or just searchBar)
注意:
可以使用OldList
调用表示完整数据集(self.tableView
)的表视图(PS约定是以小写字母启动每个变量 - 因此请更改您的属性名称{ {1}}至OldList
)。
可以使用oldList
调用表示过滤数据集(filteredList)的表视图。
当您准备好self.searchController.searchResultsTableView
数据源方法时,我怀疑您有其他数据源(可能是委托)方法需要在它们能够之前通知哪个表视图是当前表视图功能正常,为您提供完全可操作的搜索结果表视图和搜索功能。
例如:
tableView:cellForRowAtIndexPath:
和
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == self.searchController.searchResultsTableView)
return 1;
return [[self.oldList sections] count];;
}
请注意,可能有其他数据源(可能是委托)方法需要通知哪个表视图是当前表视图...我将留给您确定要修改哪些方法,以及调整表格视图所需的相应代码。
您需要为搜索结果表视图注册一个笔尖并重复使用标识符。
我更喜欢创建一个单独的nib文件(称为&#34; TableViewCellSearch.xib&#34;),其中包含一个表视图单元格,其中包含重用标识符&#34; SearchCell&#34;,然后将代码放入在以下- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchController.searchResultsTableView)
return [self.filteredList count];
return [self.oldList count];
}
委托方法中注册此nib并重用标识符。
值得注意的是,此代码在UISearchDisplayController
/ init
/ awakeFromNib
上面的代码块示例之后同样有效。
viewDidLoad
尝试这些建议。
希望这有帮助。