ios 表格视图中的搜索栏和搜索显示控制器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23410353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Search Bar and Search Display Controller in table view
提问by TheInterestedOne
I have tried to implement a search bar but I have not had any luck dealing with this problem. I would really appreciate any help that can be provided. I've a big project in which I've a table view, and I want to implement a search bar over it and see the real time filtering. I do not use Storyboard but I'm using XIB. I've added the following protocols:
我试图实现一个搜索栏,但我没有任何运气处理这个问题。我真的很感激可以提供的任何帮助。我有一个大项目,其中有一个表视图,我想在它上面实现一个搜索栏并查看实时过滤。我不使用 Storyboard,但我使用的是 XIB。我添加了以下协议:
<UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UISearchDisplayDelegate>
I've declared 2 arrays in @interface , the first for the whole elements and the second one for the filtered ones:
我在 @interface 中声明了 2 个数组,第一个用于整个元素,第二个用于过滤的元素:
NSArray* OldList;
NSArray* filteredList;
Then I've setted the number of rows and the number of sections and then:
然后我设置了行数和节数,然后:
- (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;
}
At this point, I haven't done any changes to the xib, no links and no other stuffs. If I compile I get my table, but obviously if I try to search something, nothing works. Moreover if I scroll down to the end of the table the app crashes. The real problem is that I can't see the search bar working. Could someone help me please?
在这一点上,我还没有对 xib 做任何更改,没有链接也没有其他东西。如果我编译我得到我的表,但显然如果我尝试搜索某些东西,没有任何效果。此外,如果我向下滚动到表格的末尾,应用程序就会崩溃。真正的问题是我看不到搜索栏的工作。有人可以帮我吗?
回答by andrewbuilder
Well you're on the right track... it is exactly to do with the connection of your controller class to your controller xib.
好吧,您走在正确的轨道上……这完全与您的控制器类与控制器 xib 的连接有关。
When you want to initialise a Search Bar and Search Display Controller into a UITableView, you are effectively adding a second table view that, when activated, must be managed by code in your UITableViewController
class in the same manner as any UITableView
.
当您想将搜索栏和搜索显示控制器初始化为 UITableView 时,您实际上是在添加第二个表视图,当激活该视图时,必须UITableViewController
以与任何UITableView
.
I have used these SO questions/answers to check my own answer - I recommend you take a look:
我已经使用这些 SO 问题/答案来检查我自己的答案 - 我建议您看一看:
- Creating a UISearchDisplayController programmatically
- Gray UISearchBar w/matching scope bar programmatically
I have read the Apple Documentation. I recommend you do the same to help you understand this.
我已阅读Apple 文档。我建议您也这样做以帮助您理解这一点。
First Step:
第一步:
You will need to set data source and delegate methods for both table views when you run your controller class.
运行控制器类时,您需要为两个表视图设置数据源和委托方法。
Before you do any of this, include this property...
在你做任何这些之前,包括这个属性......
@property (nonatomic, strong) UISearchDisplayController *searchController;
The following code describes how to initialise and set the appropriate properties for a UISearchBar
and a UISearchDisplayController
. If you are programmatically creating a UITableViewController
in code you will also need to set the data source and delegate for it (not shown to keep the code easy to read).
以下代码描述了如何为 aUISearchBar
和 a初始化和设置适当的属性UISearchDisplayController
。如果您以编程方式创建UITableViewController
代码,您还需要为其设置数据源和委托(未显示以保持代码易于阅读)。
You have two options here - which one you choose depends on your code and what you wish to achieve - either set these in your init
/awakeFromNib
methods, or set these in one of your table view controller (TVC) lifecycle methods.
您在这里有两个选项——您选择哪一个取决于您的代码和您希望实现的目标——要么在您的init
/awakeFromNib
方法中设置这些,要么在您的表视图控制器 (TVC) 生命周期方法之一中设置这些。
Option One - Init
选项一 - 初始化
(Note1: Paul Hegarty's extraordinary iTunesU lectures taught me to init/awake a class as follows - in this way you are covered for both scenarios - you call init or it can awakeFromNib.)
(注 1:Paul Hegarty 非凡的 iTunesU 讲座教会我按如下方式初始化/唤醒一个类——这样你就涵盖了这两种情况——你调用 init 或者它可以awakeFromNib。)
- (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;
}
OR
或者
Option Two - TVC Lifecycle
选项二 - 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 >...
}
Note2: Regardless of which of these options you choose, you will need to place the following line of code in your viewDidLoad
method...
注意2:无论您选择这些选项中的哪一个,您都需要在您的viewDidLoad
方法中放置以下代码行...
[self.tableView setTableHeaderView:self.searchController.searchBar]; // (or just searchBar)
Second Step:
第二步:
Notes:
笔记:
The table view that represents your complete data set (
OldList
) can be called usingself.tableView
(PS convention is to start each variable with lower case - so change your property name fromOldList
tooldList
).The table view that represents the filtered data set (filteredList) can be called using
self.searchController.searchResultsTableView
.
表示完整数据集 (
OldList
)的表视图可以使用self.tableView
(PS 约定是以小写开头的每个变量 - 因此将您的属性名称从 更改OldList
为oldList
)。可以使用 调用表示过滤数据集 (filteredList) 的表视图
self.searchController.searchResultsTableView
。
While you have prepared your tableView:cellForRowAtIndexPath:
data source method, I suspect you have other data source (and maybe delegate) methods that need to be informed of which table view is the current table view, before they are able to function properly and provide you with a fully operational search results table view and search function.
当您准备好tableView:cellForRowAtIndexPath:
数据源方法时,我怀疑您还有其他数据源(可能还有委托)方法需要被告知哪个表视图是当前表视图,然后才能正常运行并为您提供完整的操作搜索结果表查看和搜索功能。
For example:
例如:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == self.searchController.searchResultsTableView)
return 1;
return [[self.oldList sections] count];;
}
and:
和:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchController.searchResultsTableView)
return [self.filteredList count];
return [self.oldList count];
}
Note that there may be other data source (and maybe delegate) methods that need to be informed of which table view is the current table view... I will leave it to you to determine which of these methods are to be modified, and the corresponding code necessary to adjust the table view.
请注意,可能还有其他数据源(也可能是委托)方法需要通知哪个表视图是当前表视图……我将留给您来确定要修改这些方法中的哪些,以及调整表格视图所需的相应代码。
Third Step:
第三步:
You will be required to register a nib and reuse identifier for your search results table view.
您将需要为您的搜索结果表视图注册一个笔尖并重复使用标识符。
I prefer to create a separate nib file (called "TableViewCellSearch.xib") that contains one table view cell, with the reuse identifier "SearchCell", and then place the code to register this nib and reuse identifier in the following UISearchDisplayController
delegate method.
我更喜欢创建一个单独的 nib 文件(称为“TableViewCellSearch.xib”),其中包含一个表视图单元格,重用标识符为“SearchCell”,然后在下面的UISearchDisplayController
委托方法中放置代码来注册这个 nib 和重用标识符。
It is worth noting that this code is just as effective after the code block examples above in init
/awakeFromNib
/viewDidLoad
.
值得注意的是,该代码是在上面的代码块之后的例子一样有效init
/ awakeFromNib
/ viewDidLoad
。
- (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView {
static NSString *cellIdentifierSearch = @"SearchCell";
UINib *nib = [UINib nibWithNibName:@"TableViewCellSearch" bundle:nil];
[self.searchController.searchResultsTableView registerNib:nib forCellReuseIdentifier:cellIdentifierSearch];
}
Try these suggestions.
试试这些建议。
Hope this helps.
希望这可以帮助。