【问题标题】:UITableView updating results from UISearchBarUITableView 更新来自 UISearchBar 的结果
【发布时间】:2019-11-18 19:57:17
【问题描述】:

我有一个带有 UISearchBar 和 UITablevView 的 ViewController。 tableview 只显示数组中的项目列表,但我希望它显示过滤后的项目列表filteredArrayUsingPredicate。我可以使用谓词NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@ OR SELF LIKE[cd] %@", searchText,searchText]; 获取过滤后的数组,并且当我打印过滤后数组的计数时,项目数是正确的。但是,当我尝试在表中显示它时,会发生崩溃并出现以下错误: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]'

这是搜索栏和填充表格的代码:

@interface ViewController (){
    NSMutableArray<NSString*> *_items;
    NSMutableArray<NSString*> *_filtered;
    bool _searching;
}


@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self->_items = @[@"iphone",@"ipad",@"ipod",@"imac"];
    self->_filtered = [[NSMutableArray alloc] initWithArray:self->_items];
    self->_table.dataSource = self;
    [self->_table setDelegate:self];
    [self->_search setDelegate:self];
    self->_searching = false;

}
- (void)searchBar:(UISearchBar *)searchBar
    textDidChange:(NSString *)searchText{
    self->_searching = true;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@ OR SELF LIKE[cd] %@", searchText,searchText];
    self->_filtered = [self->_items filteredArrayUsingPredicate:predicate];
    NSLog(@"%lu",(unsigned long)[self->_filtered count]);

    [self->_table reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self->_items.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    if(self->_searching)
        cell.textLabel.text = self->_filtered[indexPath.row];
    else
        cell.textLabel.text = self->_items[indexPath.row];
    return cell;
}
@end

似乎导致崩溃的行是这个 [self-&gt;_table reloadData];- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 在该方法中,我将 search 设置为 true,并在 cellForRowAtIndexPath 中检查 search 是否为 true,然后显示过滤结果,否则显示项目。但是我不明白为什么如果我重新加载数据并告诉它显示过滤后的结果会发生崩溃。

【问题讨论】:

    标签: ios objective-c iosdeployment


    【解决方案1】:

    如果 _searching 为真,则当您应该返回过滤后的项目数时,您将返回来自 numberOfRowsInSection 的未过滤项目数。

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        if (_searching) {
            return _filtered.count;
        }
    
        return _items.count;
    }
    

    【讨论】:

    • 你知道取消搜索后显示未过滤结果的好方法吗?因为我不想到处调用 [table reload] ..
    • 不,你几乎必须调用reloadData 来重新填充表格视图,只要你想显示的数据发生这样的剧烈变化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 2020-03-30
    相关资源
    最近更新 更多