0

我有一个包含 10000 多个单元格的表格视图。顶部有一个分段按钮(全部/收藏)。

这是该段的回调:

- (IBAction)call_segment:(id)sender {

    [self.tableView beginUpdates];
    [self.tableView reloadData];
    [self.tableView endUpdates];
}

对于收藏页面,即使没有收藏项目,我也只是将单元格高度设置为 0。但是这样,我在屏幕上创建了所有 10000+ 个单元格。

如果选择了“全部”,则表格可以正常工作,因为单元格具有正常高度,并且只有其中一些单元格在屏幕上出列。

这是我的代码:

//如果不在收藏夹中,只需将其高度设置为0即可隐藏

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([self isFavorite]) {
        int uniqueId = [self uniqueIdWithIndexPath:indexPath];
        if ([DATABASE isFavoriteWithMode:self.mode uniqueId:uniqueId] == NO) {
            return 0;
        }
    }
    return 60;
}

//in table view datasource: //我认为问题是,当设置高度为0时,所有的单元格都被分配了。我将单元格设置为隐藏但仍然需要记忆。有什么办法处理吗?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    BOOL isFavorite = [DATABASE isFavoriteWithMode:self.mode uniqueId:[self uniqueIdWithIndexPath:indexPath]];

    if ([self isFavorite] && isFavorite == NO) {
        cell.hidden = YES;
        return [[UITableViewCell alloc] init];

    }
    else {
        cell.hidden = NO;
        ListCell *cell = (ListCell *)[tableView dequeueReusableCellWithIdentifier:CELL_LIST];

        Datum *datum = [DATABASE datumWithMode:self.mode uniqueId:[self uniqueIdWithIndexPath:indexPath]];


        BOOL isRead = [DATABASE isReadWithMode:self.mode uniqueId:[self uniqueIdWithIndexPath:indexPath]];


        cell.indexLabel.text = [NSString stringWithFormat:@"%d", datum.uniqueId];
        cell.titleLabel.text = [NSString stringWithFormat:@"%@", datum.q];


        return cell;
    }

}

注意:我不想只显示最喜欢的单元格,因为逻辑太复杂了。我正在使用 sqlite,但我认为数据库性能不是问题,因为“所有”选项卡工作得很好。

我只想将高度设置为 0 的原因是单元格编号的简单实现

- (BOOL)isFavorite {
    return self.segment.selectedSegmentIndex == 1;
}


- (IBAction)call_segment:(id)sender {

    [self.tableView beginUpdates];
    [self.tableView reloadData];
    [self.tableView endUpdates];
}

#define NUM_SECTIONS 15

- (int)numRows {
    return [DATABASE numberOfDataForModes:self.mode];
}

- (int)numSections {
    if ([self numRows] % NUM_SECTIONS > 0) {
        int numSections = [self numRows] / [self numRowsPerSection];
        if ([self numRows] % [self numRowsPerSection] > 0) {
            numSections++;
        }
        return numSections;
    }
    return NUM_SECTIONS;
}

- (int)numRowsPerSection {
    return [self numRows] / NUM_SECTIONS;
}

- (int)numRowsInLastSection {
    if ([self numRows] % ([self numSections] - 1) > 0) {
        return [self numRows] % ([self numSections] - 1);
    }
    else {
        return [self numRowsPerSection];
    }
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    int start = section * [self numRowsPerSection] + 1;
    int end = start + [self numRowsPerSection] - 1;
    if (end > [self numRows]) {
        end = [self numRows];
    }
    return [NSString stringWithFormat:@"From %d to %d", start, end];
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    NSMutableArray *titles = [NSMutableArray arrayWithCapacity:[self numSections]];
    int start = 1;
    while (start < [self numRows]) {

        NSString *title = [NSString stringWithFormat:@"%d", start];
        [titles addObject:title];

        start += [self numRowsPerSection];
    }

    return titles;

}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    return index;
}

- (int)uniqueIdWithIndexPath:(NSIndexPath *)indexPath {
    int uniqueId = indexPath.row + 1 + indexPath.section * [self numRowsPerSection];
    return uniqueId;
}

- (NSIndexPath *)indexPathWithUniqueId: (int)uniqueId {
    int section = (uniqueId - 1) / [self numRowsPerSection];
    int row = uniqueId - 1 - [self numRowsPerSection] * section;

    return [NSIndexPath indexPathForRow:row inSection:section];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([self isFavorite]) {
        int uniqueId = [self uniqueIdWithIndexPath:indexPath];
        if ([DATABASE isFavoriteWithMode:self.mode uniqueId:uniqueId] == NO) {
            return 0;
        }
    }
    return 60;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == [self numSections] - 1) {
        return [self numRowsInLastSection];
    }
    return [self numRowsPerSection];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [self numSections];
}
4

4 回答 4

4

而不是隐藏单元格,为什么不从数据源方法返回 0

 – tableView:numberOfRowsInSection: 

您可以在此函数中使用 isFavorite 值,如果不存在则返回 0。

于 2013-06-07T08:35:18.570 回答
3

你已经明白了。问题是不喜欢的单元格的大小为 0。这与重复使用细胞的想法相矛盾。您将在屏幕上有数千个单元格,虽然不可见但存在,因此会消耗资源。最好想一个更聪明的方法来做到这一点。您的数据源委托(我猜是视图控制器)应该只返回非收藏单元格的数量,因此cellForRowAtIndexPath应该只提供非收藏项的单元格。PluscellForRowAtIndexPath实际上应该重用我在您的代码片段中没有看到的单元格。

于 2013-06-07T08:40:00.897 回答
1

无论您如何尝试在屏幕上显示 10,000 次观看,都无法解决您的问题。您需要更改代码结构,以便在tableView:numberOfRowsInSection:选择收藏夹选项卡时可以为委托返回 0。

任何其他“解决方案”都是试图一起破解替代方案,但这不起作用,而且无论如何都是不好的代码实践。通过正确响应代表来正确实施它。

于 2013-06-07T09:00:28.153 回答
0

我已经放弃将两个表格部分分开。逻辑太复杂了。

我想即使隐藏单元格也无法节省内存。谢谢你们的意见。你们都是对的。

它实际上并没有那么糟糕,因为最喜欢的桌子通常不会那么长。只有一个部分包含所有条目。

于 2013-06-10T01:53:43.040 回答