ios - 表格 View 中的搜索栏和搜索显示 Controller

标签 ios uitableview uisearchbar uisearchdisplaycontroller

我试图实现一个搜索栏,但我没有任何运气来处理这个问题。我非常感谢可以提供的任何帮助。我有一个大项目,其中有一个表格 View ,我想在它上面实现一个搜索栏并查看实时过滤。我不使用 Storyboard,但我使用的是 XIB。我添加了以下协议(protocol):

<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 做任何更改,没有链接,也没有其他东西。如果我编译我会得到我的表,但显然如果我尝试搜索一些东西,没有任何效果。此外,如果我向下滚动到表格的末尾,应用程序就会崩溃。真正的问题是我看不到搜索栏工作。有人可以帮我吗?

最佳答案

好吧,您走在正确的轨道上……这与 Controller 类与 Controller xib 的连接完全有关。

当您想将搜索栏和搜索显示 Controller 初始化为 UITableView 时,您实际上是在添加第二个表格 View ,该 View 在激活时必须由您的 UITableViewController 中的代码管理。以与任何 UITableView 相同的方式进行分类.

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

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

  • 我已阅读 Apple Documentation .我建议您也这样做以帮助您理解这一点。

    第一步:

    运行 Controller 类时,您需要为两个 TableView 设置数据源和委托(delegate)方法。

    在您执行任何此操作之前,请包含此属性...
    @property (nonatomic, strong) UISearchDisplayController *searchController;
    

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

    您在这里有两个选项 - 您选择哪一个取决于您的代码和您希望实现的目标 - 在您的 init 中设置这些选项。/awakeFromNib方法,或在您的 TableView Controller (TVC) 生命周期方法之一中设置这些方法。

    选项一 - 初始化

    (注 1:Paul Hegarty 非凡的 iTunesU 讲座教我按如下方式初始化/唤醒类(class) - 这样您就可以涵盖两种情况 - 您可以调用 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;
    }
    



    选项二 - 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 ) 的 TableView (PS 约定是以小写字母开头的每个变量 - 因此将您的属性名称从 OldList 更改为 oldList )。
  • 可以使用 self.searchController.searchResultsTableView 调用表示过滤数据集 (filteredList) 的 TableView .

  • 当你准备好你的tableView:cellForRowAtIndexPath:数据源方法,我怀疑您还有其他数据源(可能还有委托(delegate))方法需要知道哪个 TableView 是当前 TableView ,然后它们才能正常运行并为您提供完全可操作的搜索结果 TableView 和搜索功能。

    例如:
    - (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];
    }
    

    请注意,可能还有其他数据源(也可能是委托(delegate))方法需要被告知哪个 TableView 是当前 TableView ...我将由您来确定要修改哪些方法,以及调整表格 View 所需的相应代码。

    第三步:

    您将需要为您的搜索结果 TableView 注册一个 nib 和重用标识符。

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

    值得注意的是,这段代码在上面 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];
    }
    

    试试这些建议。

    希望这可以帮助。

    关于ios - 表格 View 中的搜索栏和搜索显示 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23410353/

    相关文章:

    swift - 如何在 TableView 中居中自定义 UIView?

    ios - 'NSInvalidArgumentException '-[NSTaggedPointerString count]: unrecognized selector sent to instance 0xa006162696a614e6'

    ios - fatal error : can't unsafeBitCast between types of different sizes

    ios - UITextView 在 Objective-C 中检查文本字段是否为空

    iOS:UITableView cell.tag 数在进出 View 时不断增加

    ios - UISearchController 与单元格布局困惑

    iphone UISearchBar 完成按钮始终启用

    iphone - 当手机发生碰撞时,我可以阻止激活 Bump 功能吗?

    ios - 如何获取 SVGElement 所属的组?

    objective-c - 类和父类(super class)之间的双向通信