在表视图中搜索栏和搜索显示控制器 [英] Search Bar and Search Display Controller in table view

查看:114
本文介绍了在表视图中搜索栏和搜索显示控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现一个搜索栏,但我没有运气处理这个问题。我真的很感激可以提供任何帮助。我有一个大项目,我有一个表视图,我想在它上面实现一个搜索栏,看看实时过滤。我不使用Storyboard但我使用的是XIB。我添加了以下协议:

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:

<UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UISearchDisplayDelegate>

我在@interface中声明了2个数组,第一个用于整个元素,第二个用于已过滤的:

I've declared 2 arrays in @interface , the first for the whole elements and the second one for the filtered ones:

    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;
}

此时,我没有对xib做任何更改,没有链接,没有其他东西。如果我编译我得到我的表,但显然如果我尝试搜索某些东西,没有任何作用。此外,如果我向下滚动到表的末尾,应用程序崩溃。真正的问题是我无法看到搜索栏正常工作。有人可以帮帮我吗?

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。

Well you're on the right track... it is exactly to do with the connection of your controller class to your controller xib.

当您想要将搜索栏和搜索显示控制器初始化为UITableView时,您实际上是在添加第二个表视图,激活时,必须使用 UITableViewController 类中的代码进行管理,方法与任何 UITableView 相同。

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.

我使用这些SO问题/答案来检查我自己的答案 - 我建议你看看:

I have used these SO questions/answers to check my own answer - I recommend you take a look:

  • Creating a UISearchDisplayController programmatically
  • Gray UISearchBar w/matching scope bar programmatically

我已阅读 Apple文档。我建议你这样做,以帮助你理解这一点。

I have read the Apple Documentation. I recommend you do the same to help you understand this.

运行控制器类时,需要为两个表视图设置数据源和委托方法。

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;

以下代码描述了如何初始化和设置 UISearchBar的相应属性 UISearchDisplayController 。如果您在代码中以编程方式创建 UITableViewController ,则还需要为其设置数据源和委托(未显示以使代码易于阅读)。

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).

这里有两个选项 - 您选择哪一个取决于您的代码和您希望实现的目标 - 在 init / awakeFromNib 方法,或在您的一个表视图控制器(TVC)生命周期方法中设置它们。

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.

选项一 - 初始

(注1:Paul Hegarty非凡的iTunesU讲座教会我按照以下方式启动/唤醒课程 - 这样你就是适用于两种情况 - 您可以调用init或者它可以唤醒.FromNib。)

(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.)

- (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 方法中放置以下代码行...

Note2: Regardless of which of these options you choose, you will need to place the following line of code in your viewDidLoad method...

    [self.tableView setTableHeaderView:self.searchController.searchBar]; // (or just searchBar)



第二步:



注意:

Second Step:

Notes:


  • 表示完整数据集的表格视图( OldList )可以使用 self.tableView 调用(PS约定是以小写字母启动每个变量 - 所以更改你的属性名称从 OldList oldList )。

  • The table view that represents your complete data set (OldList) can be called using self.tableView (PS convention is to start each variable with lower case - so change your property name from OldList to oldList).

可以使用 self.searchController.searchResultsTableView 调用表示过滤数据集(filteredList)的表视图。

The table view that represents the filtered data set (filteredList) can be called using self.searchController.searchResultsTableView.

当您准备好 tableView:cellForRowAtIndexPath:数据源方法时,我怀疑您有其他数据源(也许是委托)在能够正常运行并为您提供完全可操作的搜索结果表视图和搜索功能之前,需要告知哪个表视图是当前表视图的方法。

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.

例如:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if (tableView == self.searchController.searchResultsTableView)
        return 1;
    return [[self.oldList sections] count];;
}

和:

- (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.

您需要为搜索结果表视图注册一个nib并重复使用标识符。

You will be required to register a nib and reuse identifier for your search results table view.

我更喜欢创建一个单独的nib文件(称为TableViewCellSearch.xib),其中包含一个表格视图单元格,其重用标识符为SearchCell,然后放置用于注册此nib并在以下 UISearchDisplayController 委托方法中重用标识符的代码。

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.

值得注意的是此代码上面的代码块示例在 init / awakeFromNib / viewDidLoad

It is worth noting that this code is just as effective after the code block examples above in 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];
}

尝试这些建议。

希望这有帮助。

这篇关于在表视图中搜索栏和搜索显示控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆