我正在尝试在UITextField
中使用UITableViewCell
,如下面的代码所示。似乎当tableview离开屏幕时,应该在单元格中的一些数据被混淆。我认为方法[tableView dequeueReusableCellWithIdentifier:addGroupContactCellIdentifier];
在tableview离开屏幕后无法给我一个“正确”的单元格时会出现一些问题。这是什么原因?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *addGroupContactCellIdentifier = @"AddGroupContactCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:addGroupContactCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:addGroupContactCellIdentifier];
if ([indexPath section] == 0) { // Group Name Section
cell.textLabel.text = @"Name";
UITextField *groupNameTextField = [[UITextField alloc]initWithFrame:CGRectMake(80, 10, 210, 22)];
groupNameTextField.textAlignment = UITextAlignmentLeft;
groupNameTextField.backgroundColor = [UIColor clearColor];
groupNameTextField.placeholder = @"Type Group Name";
//groupNameTextField.borderStyle = UITextBorderStyleLine;
groupNameTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
groupNameTextField.returnKeyType = UIReturnKeyDone;
groupNameTextField.autocapitalizationType = UITextAutocapitalizationTypeSentences;
groupNameTextField.delegate = self;
[cell.contentView addSubview:groupNameTextField];
}
}
if ([indexPath section] == 1) { // Contacts Section
cell.textLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"name"];
cell.detailTextLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"number"];
}
cell.accessoryType = UITableViewCellAccessoryNone;
return cell;
}
更新
所以我将UITableViewCell
子类化了,但它仍然表现出与以前相同的错误。这是我tableView:cellForRowAtIndexPath:
的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *addGroupContactCellIdentifier = @"AddGroupContactCell";
if ([indexPath section] == 0) {
UITableViewCellWithUITextField *cell = [tableView dequeueReusableCellWithIdentifier:addGroupContactCellIdentifier];
if (cell == nil) {
//cell = [[UITableViewCellWithUITextField alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:addGroupContactCellIdentifier];
cell = [[UITableViewCellWithUITextField alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:addGroupContactCellIdentifier textFieldPlaceholder:@"Type Group Name" textFieldDelegate:self];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.text = @"Name";
// Need to set the UITableViewCell's textLabel properties otherwise they will cover the UITextField
cell.textLabel.opaque = NO;
cell.textLabel.backgroundColor = [UIColor clearColor];
return cell;
} else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:addGroupContactCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:addGroupContactCellIdentifier];
}
cell.textLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"name"];
cell.detailTextLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"number"];
return cell;
}
}
第三次编辑(我现在有2个不同的reuseIdentifiers,似乎给了我想要的结果):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath section] == 0) { // Group Name Section
static NSString *groupNameCellIdentifier = @"GroupNameCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:groupNameCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:groupNameCellIdentifier];
cell.textLabel.text = @"Name";
UITextField *groupNameTextField = [[UITextField alloc]initWithFrame:CGRectMake(80, 10, 210, 22)];
groupNameTextField.textAlignment = UITextAlignmentLeft;
groupNameTextField.backgroundColor = [UIColor clearColor];
groupNameTextField.placeholder = @"Type Group Name";
//groupNameTextField.borderStyle = UITextBorderStyleLine;
groupNameTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
groupNameTextField.returnKeyType = UIReturnKeyDone;
groupNameTextField.autocapitalizationType = UITextAutocapitalizationTypeSentences;
groupNameTextField.delegate = self;
[cell.contentView addSubview:groupNameTextField];
}
// Customization
return cell;
} else {
static NSString *addGroupContactCellIdentifier = @"AddGroupContactCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:addGroupContactCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:addGroupContactCellIdentifier];
}
// Customization
cell.textLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"name"];
cell.detailTextLabel.text = [[self.selectedPeoplePickerContacts objectAtIndex:[indexPath row]] objectForKey:@"number"];
return cell;
}
}
答案 0 :(得分:1)
有些人建议不要进行子类化。
但你不能使用“if([indexPath section] == 0){”在“if(cell == nil){”之内的逻辑,因为这只是第一次创建单元格时调用它,它将在其他指数中用于后续的回收。
相反,您需要使用两个不同的CellIdentifier,以便为零部分设置的单元格不会在表中的其他位置重复使用。在将单元格出列之前,将if([indexPath section] == 0){放在第0部分和后续的单元格中使用不同的单元格标识符。
另外,请确保在“if(cell == nil){”之外执行任何特定于索引路径的操作,以便每次重复使用单元格时都会应用它,而不仅仅是第一次创建单元格时。< / p>
答案 1 :(得分:0)
你是对的!问题肯定是由于reusability
的{{1}}功能造成的。 Apple已经完成了这样的工作,以便您可以重复使用单元格,并且它在性能方面的表现非常出色!因此,当您尝试向上和向下滚动时,UITableView
值仍然相同,而您的tableView会从您在班级中定义的indexPath
获取数据!
<强>解决方案:强>
您需要继承cellForRowAtIndexPath
并在UITableViewCell
方法中添加UITextField
。
然后,您需要引用此-(void)layoutSubviews
并使用它来加载TableView。
有助于: Read this !
的链接答案 2 :(得分:0)
值混淆了,因为当你离开屏幕然后再次重新加载表格时,单元格会从内部表格单元格池中被取消,但它们的重新加载方式与之前表格中的顺序不同。请注意,即使您有一个包含许多行的表并滚动它,也会发生这种混合。解决方案是将文本字段数据存储在“数据源”数组中,然后配置单元格。
说明
基本上在您的代码中存在一个主要的概念缺陷:一旦重新生成了单元格,就不能正确配置内容(根本不配置它)。我的意思是,最初,当第一次显示表时,池是空的。因此,需要显示的每个新单元都是从头开始重新创建的(不是从池中取出);假设您的表格可以在屏幕上显示10个单元格,因此前10个单元格将全部从头开始创建,包含空文本字段。 然后你开始在这些字段中输入文本,一切正常。 在某一时刻,您开始滚动单元格:会发生的是,顶部的所有单元格将从屏幕中消失并存储(排队)在表池中,包含其文本字段及其编辑内容;假设您在第0行排队单元格。当需要在屏幕底部显示新单元格时,您的代码所做的第一件事就是尝试对单元格进行双击。现在这次你在池中有一个单元格(第0行的单元格),这个单元格从池中检索出来并放在表格中,包括第11行的TEXTFIELD内容。所以“神奇地”你会发现一个在另一行的第0行编辑的文本,11。此外,从池中以稀疏顺序检索单元格,因此在经过多次文本字段编辑和滚动后,您将完全混淆。
解决方案,这就是代码中出现错误的原因:只要创建或取消了单元格,就配置它,即设置文本字段内容。如何检索文本字段内容?存储在一个数组中。这就是您的视图控制器是“数据源”的原因,因为您可以使用数据来填充表格。由于这种去队列机制,将数据存储在表中是一个错误。例如:
groupNameTextField.text=[myTextFieldContentArray objectAtIndex:indexPath.row];
另一个解决方案,但我不建议,是为每个单元格分配一个唯一的标识符,即:
NSString *myCellId = [NSString stringWithFormat:@"CellID_%d_%d",indexPath.section,indexPath.row];
在这种情况下,所有单元格都将使用不同的名称,您永远不会混淆它们。 这个解决方案大部分时间都在工作,但由于两个原因而不鼓励: 一个。它不是最优的,因为你不重复使用单元格,因此这会占用类似单元格的额外内存 湾你无法保证每个单元都有效地排队,所有这些逻辑都在表内,并且它不会暴露给开发人员,因此可能需要在每次需要时重新生成单元(性能损失)