【问题标题】:UITableViewCell duplicating UITextfield subviews when scrollingUITableViewCell 滚动时复制 UITextfield 子视图
【发布时间】:2014-08-21 14:16:34
【问题描述】:

我试图弄清楚为什么我的SubviewsUITableview 滚动时会重复。如果我在IF statement 中添加Subviews 以重复使用单元格,它将复制并重新排序Subviews。如果我把代码放在外面,滚动时把Subviews 放在另一个上面会搞砸。下面是我的代码。我做错了什么导致这个?

static NSString *cellIdentifier = @"Cell";

UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];





cell.accessoryType = UITableViewCellAccessoryNone;

    UIColor *cellBackgroundColor = [rgbConverter convertColor:@"#202e35"];
    cell.backgroundColor = cellBackgroundColor;
    // cell.contentView.backgroundColor    = color;


    if ((indexPath.row == 0) && (indexPath.section == 0)) {
        fullName = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 200, 25)];
        fullName.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        fullName.autocorrectionType = UITextAutocorrectionTypeNo;
        [fullName setClearButtonMode:UITextFieldViewModeWhileEditing];
        fullName.textColor  = [UIColor lightGrayColor];
        [fullName setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        fullName.returnKeyType = UIReturnKeyNext;
        fullName.background = [UIImage imageNamed:@"textfieldBG.png"];
        [fullName setTag:1];
        [fullName setText:@""];

        [cell.contentView  addSubview:fullName];

    }
    if ((indexPath.row == 1)  && (indexPath.section == 0)){
        accountNumber = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 200, 25)];
        accountNumber.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        //accountNumber.placeholder = @"MLGW Account Number";
        accountNumber.autocorrectionType = UITextAutocorrectionTypeNo;
        [accountNumber setClearButtonMode:UITextFieldViewModeWhileEditing];
        accountNumber.keyboardType = UIKeyboardTypeNumberPad;
        accountNumber.returnKeyType = UIReturnKeyNext;
        accountNumber.textColor  = [UIColor lightGrayColor];
        [accountNumber setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [accountNumber setTag:2];
        [accountNumber setText:@""];
        accountNumber.background = [UIImage imageNamed:@"textfieldBG.png"];

        [cell.contentView  addSubview:accountNumber];

    }
    if ((indexPath.row == 2)  && (indexPath.section == 0)){
        address = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 200, 25)];
        address.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        address.placeholder = @"Address";
        address.autocorrectionType = UITextAutocorrectionTypeNo;
        [address setClearButtonMode:UITextFieldViewModeWhileEditing];
        address.keyboardType = UIKeyboardTypeDefault;
        address.returnKeyType = UIReturnKeyNext;
        address.textColor  = [UIColor lightGrayColor];
        [address setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [address setTag:3];
        [address setText:@""];
        address.background = [UIImage imageNamed:@"textfieldBG.png"];
        [cell.contentView  addSubview:address];

    }
    if ((indexPath.row == 3)  && (indexPath.section == 0)){
        aptNumber = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 200, 25)];
        aptNumber.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        aptNumber.placeholder = @"Apartment Number";
        aptNumber.autocorrectionType = UITextAutocorrectionTypeNo;
        aptNumber.returnKeyType = UIReturnKeyNext;
        [aptNumber setClearButtonMode:UITextFieldViewModeWhileEditing];
        aptNumber.keyboardType = UIKeyboardTypeNamePhonePad;
        aptNumber.textColor  = [UIColor lightGrayColor];
        [aptNumber setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [aptNumber setTag:4];
        [aptNumber setText:@""];
        aptNumber.background = [UIImage imageNamed:@"textfieldBG.png"];
        [cell.contentView  addSubview:aptNumber];

    }
    if ((indexPath.row == 4)  && (indexPath.section == 0)){
        city = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 180, 25)];
        city.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        city.placeholder = @"City";
        city.autocorrectionType = UITextAutocorrectionTypeNo;
        city.returnKeyType = UIReturnKeyNext;
        [city setClearButtonMode:UITextFieldViewModeWhileEditing];
        city.keyboardType = UIKeyboardTypeDefault;
        city.textColor  = [UIColor lightGrayColor];
        [city setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [city setTag:5];
        [city setText:@""];
        city.background = [UIImage imageNamed:@"textfieldBG.png"];
        [cell.contentView  addSubview:city];

        zip = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+210, cell.frame.origin.y+10,80, 25)];
        zip.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        zip.placeholder = @"Zip";
        zip.autocorrectionType = UITextAutocorrectionTypeNo;
        zip.returnKeyType = UIReturnKeyNext;
        [zip setClearButtonMode:UITextFieldViewModeWhileEditing];
        zip.keyboardType = UIKeyboardTypeNumberPad;
        zip.textColor  = [UIColor lightGrayColor];
        [zip setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [zip setTag:6];
        [zip setText:@""];
        zip.background = [UIImage imageNamed:@"textfieldBG.png"];
        [cell.contentView  addSubview:zip];

    }
     if ((indexPath.row == 5)  && (indexPath.section == 0)){
        phoneNbr = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 200, 25)];
        phoneNbr.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        phoneNbr.placeholder = @"Phone Number";
        phoneNbr.autocorrectionType = UITextAutocorrectionTypeNo;
        phoneNbr.returnKeyType = UIReturnKeyNext;
        [phoneNbr setClearButtonMode:UITextFieldViewModeWhileEditing];
        phoneNbr.keyboardType = UIKeyboardTypeNumberPad;
        phoneNbr.textColor  = [UIColor lightGrayColor];
        [phoneNbr setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [phoneNbr setTag:7];
        [phoneNbr setText:@""];
        phoneNbr.background = [UIImage imageNamed:@"textfieldBG.png"];
        [cell.contentView  addSubview:phoneNbr];

    }
    if ((indexPath.row == 6)  && (indexPath.section == 0)){
        emailAddress = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 200, 25)];
        emailAddress.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        emailAddress.placeholder = @"Email Address";
        emailAddress.returnKeyType = UIReturnKeyNext;
        emailAddress.autocorrectionType = UITextAutocorrectionTypeNo;
        [emailAddress setClearButtonMode:UITextFieldViewModeWhileEditing];
        emailAddress.keyboardType = UIKeyboardTypeEmailAddress;
        emailAddress.textColor  = [UIColor lightGrayColor];
        [emailAddress setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [emailAddress setTag:8];
        [emailAddress setText:@""];
        emailAddress.background = [UIImage imageNamed:@"textfieldBG.png"];
        [cell.contentView  addSubview:emailAddress];

    }
    if ((indexPath.row == 7)  && (indexPath.section == 0)){
        validateEmail = [[UITextField alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 200, 25)];
        validateEmail.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        validateEmail.placeholder = @"Re-enter Email Address";
        validateEmail.returnKeyType = UIReturnKeyNext;
        validateEmail.autocorrectionType = UITextAutocorrectionTypeNo;
        [validateEmail setClearButtonMode:UITextFieldViewModeWhileEditing];
        validateEmail.keyboardType = UIKeyboardTypeEmailAddress;
        validateEmail.textColor  = [UIColor lightGrayColor];
        [validateEmail setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [validateEmail setTag:9];
        [validateEmail setText:@""];
        validateEmail.background = [UIImage imageNamed:@"textfieldBG.png"];
        [cell.contentView  addSubview:validateEmail];

    }
    if ((indexPath.row == 0)  && (indexPath.section == 1)){
         oneTimeDonationBtn = [[UIButton alloc]initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 38, 32)];
        [oneTimeDonationBtn setImage:[UIImage imageNamed:@"radioBox.png"] forState:UIControlStateNormal];
        [oneTimeDonationBtn addTarget:self action:@selector(oneTimeAmountAction:) forControlEvents:UIControlEventTouchUpInside];
        oneTimeDonation = [[UITextField alloc] initWithFrame:CGRectMake(oneTimeDonationBtn.frame.origin.x+35, cell.frame.origin.y+13, 150, 25)];
        oneTimeDonation.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        oneTimeDonation.placeholder = @"One Time Donation";
        oneTimeDonation.autocorrectionType = UITextAutocorrectionTypeNo;
        oneTimeDonation.returnKeyType = UIReturnKeyNext;
        [oneTimeDonation setClearButtonMode:UITextFieldViewModeWhileEditing];
        oneTimeDonation.keyboardType = UIKeyboardTypeDecimalPad;
        oneTimeDonation.textColor  = [UIColor lightGrayColor];
        [oneTimeDonation setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [oneTimeDonation setTag:10];
        [oneTimeDonation setText:@""];
        oneTimeDonation.background = [UIImage imageNamed:@"textfieldBG.png"];
        [cell.contentView  addSubview:oneTimeDonationBtn];
        [cell.contentView  addSubview:oneTimeDonation];

    }
    if ((indexPath.row == 0) && (indexPath.section == 2)){
        oneDollarBtn = [[UIButton alloc]initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 38, 32)];
         [oneDollarBtn setImage:[UIImage imageNamed:@"radioBox.png"] forState:UIControlStateNormal];
        [oneDollarBtn addTarget:self action:@selector(oneDollarAction:) forControlEvents:UIControlEventTouchUpInside];
        [cell.contentView  addSubview:oneDollarBtn];

        oneDollarLbl = [[UILabel alloc ] initWithFrame:CGRectMake(oneDollarBtn.frame.origin.x+35, cell.frame.origin.y+10, 38, 32)];
        oneDollarLbl.text = @"$1";
        oneDollarLbl.textColor = [UIColor lightGrayColor];
        [cell.contentView  addSubview:oneDollarLbl];

        fiveDollarBtn = [[UIButton alloc]initWithFrame:CGRectMake(oneDollarLbl.frame.origin.x+35, cell.frame.origin.y+10, 38, 32)];
        [fiveDollarBtn setImage:[UIImage imageNamed:@"radioBox.png"] forState:UIControlStateNormal];
        [fiveDollarBtn addTarget:self action:@selector(fiveDollarAction:) forControlEvents:UIControlEventTouchUpInside];
        [cell.contentView  addSubview:fiveDollarBtn];

        fiveDollarLbl = [[UILabel alloc ] initWithFrame:CGRectMake(fiveDollarBtn.frame.origin.x+35, cell.frame.origin.y+10, 38, 32)];
        fiveDollarLbl.text = @"$5";
        fiveDollarLbl.textColor = [UIColor lightGrayColor];
        [cell.contentView  addSubview:fiveDollarLbl];

        tenDollarBtn = [[UIButton alloc]initWithFrame:CGRectMake(fiveDollarLbl.frame.origin.x+35, cell.frame.origin.y+10, 38, 32)];
        [tenDollarBtn setImage:[UIImage imageNamed:@"radioBox.png"] forState:UIControlStateNormal];
        [tenDollarBtn addTarget:self action:@selector(tenDollarAction:) forControlEvents:UIControlEventTouchUpInside];
        [cell.contentView  addSubview:tenDollarBtn];

        tenDollarLbl = [[UILabel alloc ] initWithFrame:CGRectMake(tenDollarBtn.frame.origin.x+35, cell.frame.origin.y+10, 38, 32)];
        tenDollarLbl.text = @"$10";
        tenDollarLbl.textColor = [UIColor lightGrayColor];
        [cell.contentView  addSubview:tenDollarLbl];
    }

if ((indexPath.row == 1)  && (indexPath.section == 2)){
    otherAmountBtn = [[UIButton alloc]initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 38, 32)];
    [otherAmountBtn setImage:[UIImage imageNamed:@"radioBox.png"] forState:UIControlStateNormal];
    [otherAmountBtn addTarget:self action:@selector(otherAmountAmountAction:) forControlEvents:UIControlEventTouchUpInside];
        otherAmount = [[UITextField alloc] initWithFrame:CGRectMake(otherAmountBtn.frame.origin.x+35, cell.frame.origin.y+13, 150, 25)];
        otherAmount.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        otherAmount.placeholder = @"Other Amount";
        otherAmount.autocorrectionType = UITextAutocorrectionTypeNo;
        otherAmount.returnKeyType = UIReturnKeyNext;
        [otherAmount setClearButtonMode:UITextFieldViewModeWhileEditing];
        otherAmount.keyboardType = UIKeyboardTypeDecimalPad;
        otherAmount.textColor  = [UIColor lightGrayColor];
        [otherAmount setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
        [otherAmount setTag:10];
        [otherAmount setText:@""];
        otherAmount.background = [UIImage imageNamed:@"textfieldBG.png"];
    [cell.contentView  addSubview:otherAmountBtn];
        [cell.contentView  addSubview:otherAmount];

    }


    if ((indexPath.row == 0)  && (indexPath.section == 3)){
        comments = [[UITextView alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+10, 280, 100)];
        comments.font = [UIFont fontWithName:@"HelveticaNeue" size:15];
        comments.autocorrectionType = UITextAutocorrectionTypeNo;
        comments.keyboardType = UIKeyboardTypeDefault;
        comments.textColor  = [UIColor lightGrayColor];
        [comments setTag:11];
        [comments setText:@""];
        comments.contentInset = UIEdgeInsetsMake(2.0, 1.0, 0.0, 0.0);
        [cell.contentView  addSubview:comments];


    }
}


//cell.imageView.image = [UIImage imageNamed:@"settings_icon.png"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.backgroundColor = [UIColor clearColor];

return cell;
}

【问题讨论】:

  • 正如其他人所暗示的那样,如果您成功检索到“可重用”单元格,如果您已添加视图,则必须在继续之前对其进行“清理”。
  • 您可以在添加新的子视图之前删除以前的子视图。如果 else 循环,把它放在你面前

标签: ios uitableview addsubview


【解决方案1】:

当您仅使用一个 cellIdentifier 通过调用 dequeueReusableCellWithIdentifier 方法重用不同类型的单元格时,就会发生这种情况。

在您的代码中,您在不同的 indexPath 添加不同的视图,但您不知道 dequeueReusableCellWithIdentifier 方法给出的单元格是什么。

例如,当您将address 视图添加到重复使用的单元格时,它可能已经有一个fullName 子视图。然后你会得到意想不到的结果。

解决问题的方法有很多。

这里有两个我觉得很适合你的情况,你可以选择任何你喜欢的:

  1. 由于您的单元格内容不是那么“可重复使用”,如果性能没有问题,我建议您根本不要使用dequeueReusableCellWithIdentifier

  2. 你最好为不同类型的单元格使用不同的cellIdentifier

【讨论】:

    【解决方案2】:

    主要原因是dequeueReusableCellWithIdentifier,顾名思义,无论顺序如何,都会获取一个已经创建的单元格。我猜它只缓存与可见单元格一样多的单元格。

    当您向上滚动时,它会为您提供一个已创建(并已填充)的单元格。

    用这个替换单元格的创建:

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 
    

    同时删除 if (cell == nil)。同时删除其他单元格创建

    请记住 dequeueReusableCellWithIdentifier:forIndexPath: 永远不会返回 nil。因此,最好检查单元格是否已填充以跳过子视图的创建。

    【讨论】:

      【解决方案3】:

      你的代码有点难读。

      每次你必须自定义单元格时,你不应该使用UITableViewCell,而是应该继承它,并在你的自定义类中自定义它。

      根据我的经验,当涉及部分和行时,我发现 if 语句很复杂。

      我建议你使用 switch 语句,你可以为每个案例提供逻辑。

      这将使您的生活更轻松,大致如下:

      - (UITableViewCell *)tableView:(UITableView *)tableView 
                                    cellForRowAtIndexPath:(NSIndexPath *)indexPath
      {
          switch (indexPath.section) {
              case 0:
                  switch (indexPath.row) {
                      case 0:
                          //fullName custom cell
                          break;
                      case 1:
                          //account number custom cell
                          break;
      
                      default:
                          break;
                  }
                  break;
      
              default:
                  break;
          }
      
          return cell;
      
      }
      

      【讨论】:

        【解决方案4】:

        首先将文本字段标签设置为某个常量,您可以使用单元格 indexPath 获取文本字段。其次添加文本字段,如果它还没有,如下所示;

        - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
         {
             static NSString *cellIdentifier = @"Cell";
        
             UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        
             //check if you already have textfield, say a constant tag is 100
             UITextField *myTextField ;
        
            if(cell){
        
                    myTextField = (UITextField *)[cell.contentView viewWithTag:100];
            }
        
            if (cell == nil) {
                       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        
            //now if myTextField is nil then only init it
            if(!myTextField){
                   //Configure textfield here and add to cell content view
            }
        
        
         }
        
        //now all things are configure for cell , assign whatever text you want to myTextField
        if(indexPath.row == 0 && indexPath.section == 0){
        
          //.......
          [myTextField setText:@"XYZ"];
        
        
        
        }
        
        }
        

        【讨论】:

          猜你喜欢
          • 2012-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-23
          • 1970-01-01
          相关资源
          最近更新 更多