简体   繁体   English

UITableView,不可见区域中的另一个单元格带有选中标记,而触摸了可见区域中的一个

[英]UITableView, another cell in invisible area has a checkmark while one in visible area is touched

This is my code, which shows a problem for 14 rows of a table view. 这是我的代码,它显示了表视图的14行有问题。 For one screen, 6 cells are visible. 对于一个屏幕,可以看到6个单元格。

When I tapped the 2nd cell, the 10 cell also has a checkmark, tap 3rd then 11th checkmarked, 1st then 9th checkmarked, tap 1st, then 8th also checkmarked...but the grey highlight does not behave like this, only one cell can be highlighted. 当我点击第2个单元格时,第10个单元格也有一个复选标记,依次点击第3个和第11个复选标记,第一个然后第9个复选标记,点击第1个,然后第8个复选标记...但是灰色高亮显示的行为并不像这样,只有一个单元格可以突出显示。

If I tap a cell after one is tapped on the the same screen, the one just checkmarked will be cleared for checkmark, which makes sense. 如果在同一屏幕上点击一个单元格后我点击了一个单元格,则刚才选中的那个单元格将被清除以选中标记,这很有意义。 However, if after I tapped one cell and then scroll the tableview lower, I can tap a cell and it shows checkmark as well, ie the one just checked on top screen still has a checkmark. 但是,如果在点击一个单元格然后向下滚动表格视图之后,我可以点击一个单元格并显示对号,即刚在顶部屏幕上选中的那个单元格仍带有对号。 So if I scroll up and down, and tap one cell each time after I scroll to the other side, I can put a checkmark for every cell, all checkmarks are shown. 因此,如果我上下滚动并在滚动到另一侧后每次点击一个单元格,则可以为每个单元格都打一个勾号,所有勾号都会显示出来。

It is really weird, and I have tried a lot of ways to solve it, but seems I have some basic understanding of UITableView missing, can anyone figure it out, please? 真的很奇怪,我尝试了很多方法来解决它,但是似乎我对UITableView缺少一些基本的了解,请问有人可以解决吗? Thanks. 谢谢。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID= @"UITableViewCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }

    cell.imageView.image = [UIImage imageNamed:@"earth.png"];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
{
    UITableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath];    
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryNone;
}

You're not storing the existence/absence of your checkmark in any sort of persisted data source and showing/hiding it in cellForRowAtIndexPath . 您不会将选中标记的存在/不存在存储在任何类型的持久数据源中,也不会将其显示/隐藏在cellForRowAtIndexPath Because of this, your table is reusing your cells, and it just throws it up as it found it. 因此,您的表正在重用您的单元格,它只是在找到它时将其抛出。 So if it reuses a cell that had your checkmark accessory enabled, it shows it as enabled (because you didn't specifically disable it in cellForRow ) 因此,如果它重复使用启用了选中标记附件的单元格,则会将其显示为启用状态(因为您没有在cellForRow专门禁用它)

I would keep an NSMutableArray of selected indexPath objects. 我将保留NSMutableArray所选的indexPath对象。 Add the indexPath in didSelectRowAtIndexPath , and remove it in didDeselectRowAtIndexPath . didSelectRowAtIndexPath添加indexPath ,并在didDeselectRowAtIndexPath其删除。 Then, in cellForRowAtIndexPath , check if the current indexPath exists in the array and enable the checkmark if so, disable if not. 然后,在cellForRowAtIndexPath ,检查当前indexPath存在于数组中,如果存在则启用复选标记,否则将其禁用。

Stonz2's answer is right. Stonz2的答案是正确的。 For example, you should create an object for table view data source and it should has a property to show is it checkmarked. 例如,您应该为表视图数据源创建一个对象,并且该对象应具有要选中的属性以显示。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:     (NSIndexPath *)indexPath
{
    ...

    Item *item = [self.itemArray objectAtIndex:indexPath.row];
    if (item.checkmarked) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    Item *tappedItem = [self.itemArray objectAtIndex:indexPath.row];
    tappedItem.checkmarked = !tappedItem.checkmarked;
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM