tableView 滚动时添加了重复的 UITextField

Posted

技术标签:

【中文标题】tableView 滚动时添加了重复的 UITextField【英文标题】:Duplicate UITextField's being added when tableView scrolls 【发布时间】:2014-02-11 14:59:20 【问题描述】:

我遇到了一个问题,即重复使用单元格时添加了重复的 UITextField,这不是我想要发生的。我记得以前遇到过类似的问题,但是对于我的生活,我不记得我做了什么来解决它。

毫无疑问,这很明显,但我似乎找不到任何有用的东西。正如某些人所建议的那样,我已经尝试将 if/else 语句包含在“if (cell == null)”中,但这只会导致形成一个空白表。

我们将不胜感激一些建议。

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

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];


        if (indexPath.section == 0)

            productField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
            [productField setPlaceholder:@"Product"];
            if ([productData length] > 0)
                [productField setText:productData];
                [productField setEnabled:false];
            
            [cell addSubview:productField];

         else if (indexPath.section == 1)

            issueField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
            [issueField setPlaceholder:@"What's the issue?"];
            [issueField setAutocorrectionType:UITextAutocorrectionTypeNo];
            [cell addSubview:issueField];

         else if (indexPath.section == 2)

            emailField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
            [emailField setPlaceholder:@"Email address"];
            [emailField setAutocorrectionType:UITextAutocorrectionTypeNo];
            [emailField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
            [emailField setKeyboardType:UIKeyboardTypeEmailAddress];
            [cell addSubview:emailField];

         else if (indexPath.section == 3)

            notesField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
            [notesField setPlaceholder:@"Any notes to add?"];
            [notesField setAutocorrectionType:UITextAutocorrectionTypeNo];
            [cell addSubview:notesField];

         else if (indexPath.section == 4)

            sendFeedback = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
            [sendFeedback setTitle:@"Send Feedback" forState:UIControlStateNormal];
            [sendFeedback setBackgroundColor:[UIColor colorWithRed:(111/255.0f) green:(31/255.0f) blue:(68/255.0f) alpha:1.0f]];
            [sendFeedback.titleLabel setFont:[UIFont fontWithName:@"MaryAnn" size:20.0]];
            [sendFeedback addTarget:self action:@selector(sendFeedback:) forControlEvents:UIControlEventTouchUpInside];
            [cell setBackgroundColor:[UIColor clearColor]];
            [cell addSubview:sendFeedback];

        


    return cell;

【问题讨论】:

你应该使用静态单元格代替 dequeueReusableCell 它们。 你不能创建自定义单元格吗? 感谢您的帮助。我选择了静态单元格(完全忘记了它们),因为它只会在测试版本中使用,而不是在应用程序的生产版本中使用。 【参考方案1】:

你的问题是表格视图中的可重用单元格,试试这个代码

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

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if(cell == nil)
    
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.selectionStyle=UITableViewCellSelectionStyleNone;
        UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
        textField.tag=101;
        [cell addSubview:textField];

        UIButton *sendFeedback = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
        sendFeedback.tag=102;
        [sendFeedback setTitle:@"Send Feedback" forState:UIControlStateNormal];
        [sendFeedback setBackgroundColor:[UIColor colorWithRed:(111/255.0f) green:(31/255.0f) blue:(68/255.0f) alpha:1.0f]];
        [sendFeedback.titleLabel setFont:[UIFont fontWithName:@"MaryAnn" size:20.0]];
        [sendFeedback addTarget:self action:@selector(sendFeedback:) forControlEvents:UIControlEventTouchUpInside];
        [cell setBackgroundColor:[UIColor clearColor]];
        [cell addSubview:sendFeedback];

    
    UITextField* textField=(UITextField*)[cell viewWithTag:101];
    UIButton *sendFeedback = (UIButton*)[cell viewWithTag:102];
    sendFeedback.hidden=YES;
    textField.hidden=NO;
     [textField setKeyboardType:UIKeyboardTypeDefault];
    if (indexPath.section == 0)
    
        [textField setPlaceholder:@"Product"];
        if ([productData length] > 0)
        
            [textField setText:productData];
            [textField setEnabled:false];
        

     else if (indexPath.section == 1)

        [textField setPlaceholder:@"What's the issue?"];
        [textField setAutocorrectionType:UITextAutocorrectionTypeNo];

     else if (indexPath.section == 2)

        [textField setPlaceholder:@"Email address"];
        [textField setAutocorrectionType:UITextAutocorrectionTypeNo];
        [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
        [textField setKeyboardType:UIKeyboardTypeEmailAddress];

     else if (indexPath.section == 3)

        [textField setPlaceholder:@"Any notes to add?"];
        [textField setAutocorrectionType:UITextAutocorrectionTypeNo];

     else if (indexPath.section == 4)
    
        textField.hidden=YES;
        sendFeedback.hidden=NO;
    

    return cell;

// 在表格视图中不能直接访问 textField.text,而是使用全局变量或字典来分配 textField.text

【讨论】:

【参考方案2】:

这是因为您不断将子视图添加到单元格中。例如,您将 productField 添加到索引 0 处的单元格。当该单元格被重用时,您向其添加另一个子视图,但 productField 仍然存在。一种可能的解决方案是在添加新子视图之前删除子视图。你的if 声明会是这样的:

    if (indexPath.section == 0)
        // Remove the old subview
        UIView *oldSubview = [cell viewWithTag:5];
        [oldSubview removeFromSuperview];

        productField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
        [productField setPlaceholder:@"Product"];
        if ([productData length] > 0)
            [productField setText:productData];
            [productField setEnabled:false];
        
        // Set a tag for the new subview, so you can remove it later
        productField.tag = 5;
        [cell addSubview:productField];
    

在每个if 语句中使用相同的tag

编辑:

或者你也可以像@pawan 建议的那样使用静态单元格。

【讨论】:

【参考方案3】:

问题在于,由于您正在回收单元格(并且应该),因此您正在重用非空单元格并在其上添加新控件。

通常的处理方法是构建您的自定义 UITableViewCell 子类,并将各种文本字段和其他 UI 控件作为属性。 然后您可以在每个部分中显示/隐藏这些 UI 控件

看起来像这样:

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

    static NSString *CellIdentifier = @"Cell";
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
        if (indexPath.section == 0)
            productField.hidden=NO;
            issueField.hidden=YES;

         else if (indexPath.section == 1)
            productField.hidden=YES;
            issueField.hidden=NO;
        
return cell;

【讨论】:

【参考方案4】:

为什么不实例化单元格后,从单元格内容视图中删除所有子视图

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

【讨论】:

【参考方案5】:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    NSString *CellIdentifier = [NSString stringWithFormat:@"Cell %d",indexPath.section];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell = nil;
    if (cell == nil)
    

    if (indexPath.section == 0)
    

        productField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
        [productField setPlaceholder:@"Product"];
        if ([productData length] > 0)
            [productField setText:productData];
            [productField setEnabled:false];
        
        [cell addSubview:productField];

    
    else if (indexPath.section == 1)
    

        issueField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
        [issueField setPlaceholder:@"What's the issue?"];
        [issueField setAutocorrectionType:UITextAutocorrectionTypeNo];
        [cell addSubview:issueField];

     else if (indexPath.section == 2)

        emailField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
        [emailField setPlaceholder:@"Email address"];
        [emailField setAutocorrectionType:UITextAutocorrectionTypeNo];
        [emailField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
        [emailField setKeyboardType:UIKeyboardTypeEmailAddress];
        [cell addSubview:emailField];

     else if (indexPath.section == 3)

        notesField = [[UITextField alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
        [notesField setPlaceholder:@"Any notes to add?"];
        [notesField setAutocorrectionType:UITextAutocorrectionTypeNo];
        [cell addSubview:notesField];

     else if (indexPath.section == 4)

        sendFeedback = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 300, 45)];
        [sendFeedback setTitle:@"Send Feedback" forState:UIControlStateNormal];
        [sendFeedback setBackgroundColor:[UIColor colorWithRed:(111/255.0f) green:(31/255.0f) blue:(68/255.0f) alpha:1.0f]];
        [sendFeedback.titleLabel setFont:[UIFont fontWithName:@"MaryAnn" size:20.0]];
        [sendFeedback addTarget:self action:@selector(sendFeedback:) forControlEvents:UIControlEventTouchUpInside];
        [cell setBackgroundColor:[UIColor clearColor]];
        [cell addSubview:sendFeedback];

    

    
    return cell;

【讨论】:

以上是关于tableView 滚动时添加了重复的 UITextField的主要内容,如果未能解决你的问题,请参考以下文章

滚动时tableview数据重复

插入新行时 TableView 滚动到中间

添加新数据时,Tableview 会滚动到顶部。无限滚动

如何为每次用户滚动时更新的每个 tableview 单元格添加一个计时器?

滚动时 UITableView 中的数据重复

如何将 panGestureRecognizer 添加到 TableView,并且在识别平底锅时仍然让 tableview 滚动?