【问题标题】:Wrong Cell's value in TableView after searching搜索后 TableView 中 Cell 的值错误
【发布时间】:2013-11-10 07:59:29
【问题描述】:

大家好

我的项目中有两个这样的数组

- (void)viewDidLoad
    {
        [super viewDidLoad];
        deviceName = [[NSArray alloc] initWithObjects: @"iPhone", @"Galaxy", @"iPad", @"iMac", @"HTC One", nil];
        companyName = [[NSArray alloc] initWithObjects:@"Apple", @"Samsung", @"Apple", @"Apple", @"HTC", nil];
    }

我正在使用此代码修改单元格..

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [searchResult count];
    } else {
        return [deviceName count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
    }

        if ([self.searchDisplayController isActive]) {

            NSString *name = [searchResult objectAtIndex:indexPath.row];
            NSString *company = [companyName objectAtIndex:indexPath.row];
            cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", name, company];

        } else {

            NSString *name = [deviceName objectAtIndex:indexPath.row];
            NSString *company = [companyName objectAtIndex:indexPath.row];
            cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", name, company];
        }
    return cell;
}

我正在使用此代码进行搜索..

#pragma mark - UISearchDisplayController delegate methods

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate
                                    predicateWithFormat:@"SELF contains[cd] %@",
                                    searchText];
    [searchResult release];
    searchResult = [[deviceName filteredArrayUsingPredicate:resultPredicate]retain];
}

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentForSearchText:searchString
                               scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                      objectAtIndex:[self.searchDisplayController.searchBar
                                                     selectedScopeButtonIndex]]];
    return YES;
}

一开始细胞是这样的

cell1- iPhone - 苹果

cell2- Galaxy - Samaung

...

当我搜索“htc”时,搜索工作正常,但像这样的单元格

cell1- HTC One - 苹果

...

我能做些什么来解决这个问题?

【问题讨论】:

    标签: ios uitableview searchdisplaycontroller


    【解决方案1】:

    您有两个单独的数组作为表视图数据源:

    deviceName  = [ "iPhone", "Galaxy", "iPad", "iMac", "HTC One"]
    companyName = [ "Apple", "Samsung", "Apple", "Apple", "HTC" ]
    

    然后,在您的示例中,您从 deviceName 创建一个过滤数组

    searchResult = [ "HTC One"]
    

    cellForRowAtIndexPath 中,您使用过滤后的数组和原始 数组companyName,这就是显示“HTC One - Apple”的原因。

    为了解决这个问题,你不应该使用两个单独的数组作为数据源, 而是一个单个字典数组,其中每个字典都包含设备名称和 公司名称:

    allDevices = @[
                @{@"name": @"iPhone", @"company": @"Apple"},
                @{@"name": @"Galaxy", @"company": @"Samsung"},
                ...
                ];
    

    你可以像这样过滤数组:

    NSPredicate *resultPredicate = [NSPredicate
                                    predicateWithFormat:@"name CONTAINS[cd] %@",
                                    searchText];
    filteredDevices = [allDevices filteredArrayUsingPredicate:resultPredicate];
    

    所以filteredDevices 也是一个字典数组,包含名称​​和 公司为每个设备。然后,在cellForRowAtIndexPath,你可以简单地做

    NSDictionary *device;
    if ([self.searchDisplayController isActive]) {
        device = filteredDevices[indexPath.row];
    } else {
        device = allDevices[indexPath.row];
    }
    NSString *name = device[@"name"];
    NSString *company = device[@"company"];
    cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", name, company];
    

    备注:我省略了所有保留/释放调用,因为我通常使用 ARC。

    【讨论】:

    • @WissamiOS:异常发生在哪一行?
    • searchResult = [allDevices filteredArrayUsingPredicate:resultPredicate]; (lldb)
    • @WissamiOS:你在那条线上遇到了什么错误? - 我已经测试了谓词,它对我来说是正确的。
    • @WissamiOS:正如我所说,我的代码示例假定为 ARC(自动引用计数)。您的项目不使用 ARC,因此您必须保留 allDevicesfilteredDevices(或使用“保留的属性”),否则您将遇到内存损坏(这就是您的情况)。 - 或者更好地使用 ARC !
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    • 2017-05-30
    • 2020-06-03
    • 2019-01-01
    相关资源
    最近更新 更多