UITableView indexPath section logic

5

这是我的cellForRowAtIndexPathUITableView代理方法的简略代码:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"blahblahblah"];
if (cell == nil) {
    // No cell to reuse => create a new one
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"blahblahblah"] autorelease];
}
cell.textLabel.text = @"";
cell.detailTextLabel.text = @"";
cell.backgroundView = NULL; //problem here

// Initialize cell
//blah blah blah
//now to the good part...

if(indexPath.section == 1) {
    cell.backgroundView = deleteButton;
    cell.userInteractionEnabled = YES;
    cell.textLabel.text = nil;
    cell.detailTextLabel.text = nil;
}

else if(indexPath.section == 0) {
    NSLog(@"section: %i row: %i", indexPath.section, indexPath.row);
    switch (indexPath.row) {
        case 0:
            cell.textLabel.text = @"foobar";
            //more stuff
            break;

        //lots more cases

        default:
            break;
    }
}

return cell;

我的问题是,第一节中的第一个单元格(第0节有10个单元格,第1节只有1个单元格)被分配了应该分配给第一节的单元格0的信息。 因此,它得到了标签标题“foobar”,而不是删除按钮背景等。 我不太确定为什么会发生这种情况,因为我的if语句非常清晰。 有任何想法吗?
编辑:将backgroundView设置为NULL会导致那些具有文本的单元格在离开视图时回来没有任何背景。因此,这不是可行的解决方案。 此外,detailTextLabel的文本仍然设置在不应该有任何文本的单元格上。
这就是它的外观,将单元格backgroundViews设置为nil并在不应该出现的删除单元格上显示文本:
![enter image description here](https://istack.dev59.com/l5oI6.webp)
解决方案,如Alex Deem建议的(用此代码替换旧的dequeue代码):
NSString* identifier;
if(indexPath.section == 0)
    identifier = @"0";
else
    identifier = @"1";
UISwitch *switchView;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
    // No cell to reuse => create a new one
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier] autorelease];
3个回答

5

你应该阅读有关单元格重用的文档。

每个部分应使用不同的reuseIdentifier,因为它们是基本上不同风格的单元格。


啊,是的,就是这样。已经用解决方案更新了问题。 - eric.mitchell

0

在这些代码行中添加一个闭合的}括号:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"blahblahblah"];
if (cell == nil) {
    // No cell to reuse => create a new one
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"blahblahblah"] autorelease];
}
....
....
....
if(indexPath.section == 1) {
   ....
   ....
}
if(indexPath.section == 0) {
   ....
   ....
}

我猜你在表格中会得到更好的结果。

目前的情况是(至少根据你的代码),你创建了一个单元格并将其初始化为某些内容。它从未被重置为任何其他请求的值和数据。


这样做不行——现在它们各自所在的部分中,行0的两个单元格都会同时显示来自部分0单元格的文本和来自部分1单元格的背景。但是我无意中发现,使用不同的标识符为dequeueReusableCellWithIndentifier和reuseIndentifier解决了这个问题...这是一种不好的做法吗? - eric.mitchell
请更新您的原始问题,并使用新代码...是的,在单个表视图中,标识符应该是相同的。 - Michael Dautermann
在执行 if (indexPath.section == 1) 之前,加上 cell.textLabel.text = @"";cell.backgroundView = NULL;。这样应该可以解决最后两个问题。哦,还有,在那个 if 的前面真的有一个 else 吗?上面没有对应的 if / then 吗? - Michael Dautermann
PROBLEM HERE这个表示什么意思?问题出在哪里? - Michael Dautermann

0

你的代码结构不正确。

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"blahblahblah"];
if (cell == nil) 

dqueueReuseableCellWithIdentifier会返回一个已经创建过的cell,如果它不再使用。如果cell == nil,你应该创建一个新的cell,并设置所有cell都共用的默认值。然而,任何针对该indexPath特定数据的设置都应该在此之后进行。
if(cell==nil) block.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"blahblahblah"];
if (cell == nil) 
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1         reuseIdentifier:@"blahblahblah"] autorelease];
}
cell.textLabel.text=@"unique text";
return cell;

请查看我在Micheal Dautermann的回答下发布的评论。 - eric.mitchell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接