UITableViewCell 滚动时复制 UITextfield 子视图
Posted
技术标签:
【中文标题】UITableViewCell 滚动时复制 UITextfield 子视图【英文标题】:UITableViewCell duplicating UITextfield subviews when scrolling 【发布时间】:2014-08-21 14:16:34 【问题描述】:我试图弄清楚为什么我的Subviews
在UITableview
滚动时会重复。如果我在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 循环,把它放在你面前 【参考方案1】:当您仅使用一个 cellIdentifier
通过调用 dequeueReusableCellWithIdentifier
方法重用不同类型的单元格时,就会发生这种情况。
在您的代码中,您在不同的 indexPath 添加不同的视图,但您不知道 dequeueReusableCellWithIdentifier
方法给出的单元格是什么。
例如,当您将address
视图添加到重复使用的单元格时,它可能已经有一个fullName
子视图。然后你会得到意想不到的结果。
解决问题的方法有很多。
这里有两个我觉得很适合你的情况,你可以选择任何你喜欢的:
由于您的单元格内容不是那么“可重复使用”,如果性能没有问题,我建议您根本不要使用dequeueReusableCellWithIdentifier
。
你最好为不同类型的单元格使用不同的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"];
【讨论】:
以上是关于UITableViewCell 滚动时复制 UITextfield 子视图的主要内容,如果未能解决你的问题,请参考以下文章
键盘出现时如何滚动 UITableviewcell 向上滚动? [复制]
UITableViewCell 滚动时复制 UITextfield 子视图