第一个和最后一个 UITableViewCell 在滚动时不断变化

Posted

技术标签:

【中文标题】第一个和最后一个 UITableViewCell 在滚动时不断变化【英文标题】:First and last UITableViewCell keep changing while scrolling 【发布时间】:2011-01-08 20:02:28 【问题描述】:

我有一个表格视图,其中的单元格包含一个 UITextField 作为每个单元格的子视图。我的问题是,当我向下滚动时,第一个单元格中的文本在最后一个单元格中重复。如果我弄清楚原因,我就无法终生。我尝试从不同的笔尖加载单元格,将 textFields 作为 ivars。 UITextFields 似乎不是问题,我认为这与 tableView 重用单元格有关。

文本字段都有一个数据源,用于跟踪文本字段中的文本,并且每次显示单元格时都会重置文本。

有什么想法吗?我真的很感激这个问题的更多答案。

更新 2: 这是我用于自定义单元格的代码,称为 JournalCell。非常感谢您的反馈。

我有 8 个部分,每个部分 1 行。前 7 个有一个 textField,最后一个是一个像按钮一样的单元格。

我正在测试按钮单元格,如果它与第 (7) 节匹配,则返回该单元格,如果不匹配,则继续其余的单元格。会是这样吗?

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

NSLog(@"Section %i, Row %i", indexPath.section, indexPath.row);


if (indexPath.section == 7) 

    static NSString *ButtonCellIdentifier = @"ButtonCellIdentifier";

    UITableViewCell *buttonCell = [self.tableView dequeueReusableCellWithIdentifier:ButtonCellIdentifier];

    if (buttonCell == nil) 
        buttonCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ButtonCellIdentifier] autorelease];
        buttonCell.selectionStyle = UITableViewCellSelectionStyleBlue;
        buttonCell.accessoryType = UITableViewCellAccessoryNone;
        buttonCell.textLabel.text = sClearAll;
        buttonCell.textLabel.textAlignment = UITextAlignmentCenter;
        buttonCell.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.8];
        buttonCell.textLabel.backgroundColor = [UIColor clearColor];
    

    return buttonCell;


static NSString *TextCellIdentifier = @"JournalCellIdentifier";

JournalCell *cell = (JournalCell *)[self.tableView dequeueReusableCellWithIdentifier:TextCellIdentifier];
if (cell == nil) 
    [[NSBundle mainBundle] loadNibNamed:@"JournalCell" owner:self options:nil];
    cell = customCell;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.accessoryType = UITableViewCellAccessoryNone;

    cell.textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
    cell.textField.returnKeyType = UIReturnKeyNext;
    cell.textField.clearButtonMode = UITextFieldViewModeWhileEditing;
 

switch (indexPath.section) 
    case 0:
        switch (indexPath.row) 
            case 0:
                cell.textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
                self.authorTextField = cell.textField;
                self.authorTextField.text = [self.textFieldDictionary objectForKey:@"author"];
                NSLog(@"Reading Author:%@", [self.textFieldDictionary objectForKey:@"author"]);
                break;
        
        break;

    case 1:
        switch (indexPath.row) 
            case 0:
                self.yearTextField = cell.textField;
                self.yearTextField.text = [self.textFieldDictionary objectForKey:@"year"];
                NSLog(@"Reading Year:%@", [self.textFieldDictionary objectForKey:@"year"]);
                break;                  
        
        break;

    case 2:
        switch (indexPath.row) 
            case 0:
                self.volumeTextField = cell.textField;
                self.volumeTextField.text = [self.textFieldDictionary objectForKey:@"volume"];
                NSLog(@"Reading Volume:%@", [self.textFieldDictionary objectForKey:@"volume"]);
                break;                      
        
        break;

    case 3:
        switch (indexPath.row) 
            case 0:
                self.articleTextField = cell.textField;
                self.articleTextField.text = [self.textFieldDictionary objectForKey:@"article"];
                NSLog(@"Reading Article:%@", [self.textFieldDictionary objectForKey:@"article"]);
                break;          
        
        break;

    default:
        break;


return cell;

【问题讨论】:

提供一些示例代码以便我们定位问题;) 您在正确使用单元格时遇到了一些问题。发布您的 cellForRowAtIndexPath: 方法,以便我们帮助修复它 我更新了示例代码以反映我用于自定义单元格的内容。 有人对我发布的新代码有反馈吗? 【参考方案1】:

正如您所猜测的,问题很可能来自 UITableView 中单元格的传统重用。创建一个 NSMutableDictionary 作为类的属性,每当 UITextField 完成编辑时,将其值设置为字典中的键。

然后,在您的cellForRowAtIndexPath 方法中,加载字典中相应键的值。

最好用[indexPath section], [indexPath row] 格式命名字典中的每个键,因为这将有助于设置和获取值。

希望这会有所帮助。

【讨论】:

【参考方案2】:

Canada Dev 的回答可能会解决您的问题,但这只是权宜之计,而不是长期修复。

您应该避免在 cellForRowAtIndexPath: 方法中添加子视图。

您应该创建一个自定义 UITableViewCell(通常通过子类化 UITableViewCell)并使用它 - 否则您在单元格出列时添加/删除子视图。

如果您不确定单元格出队的实际含义,您可能应该阅读 Apple 的 TableView 文档。基本上,使用 UITableViewCell 子类,与尝试在 cellForRow 方法中添加所有视图相比,您将处于更好的位置。

【讨论】:

我使用的是带有 textField 属性的自定义单元格。它在做同样的事情。基本上,我只希望每个单元格中都有一个 UITextField,我可以通过 UITextFieldDelegate 访问它。如果有人可以发布一些示例代码的大纲,我将不胜感激。【参考方案3】:

您真的需要将每个单元格和textField 保存到您的viewController,然后通过插入其他单元格中的部分来生成单元格吗?

也许您可以将整个单元格保存在一个属性中(例如self.authorCell),然后简单地显示这个单元格:

if (indexPath.section == 0) 
    return self.authorCell; // or cell = self.authorCell

您仍然可以通过访问单元格属性来访问textField

self.authorCell.myTextField

// 编辑:请参阅 Apple documentation 的“静态行内容技术”

【讨论】:

这可能有效。我稍后会尝试。我试图将单元格设置为我想要返回的单元格。我现在看到了我的错误。【参考方案4】:

尝试在分配单元格之后和进行任何绘图/标签/等之前插入它。

cell.clearsContextBeforeDrawing = YES;

cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;

for (UIView *view in cell.contentView.subviews) 
    [view removeFromSuperview];

【讨论】:

以上是关于第一个和最后一个 UITableViewCell 在滚动时不断变化的主要内容,如果未能解决你的问题,请参考以下文章

最后一个 UITableViewCell 没有分隔线

重新排序单元格后重新加载自定义 UITableViewCell

如何更改最后一个 UITableViewCell 的特定约束?

检测UITableView中当前可见的最后一个UITableViewCell

在 iOS 7 中为 UITableViewCell 使用背景视图涵盖了默认删除按钮

为啥imageView的底部和UILabel中的第一个UITableViewCell之间有空格?