我的MainViewController中有一个UITableView。当用户点击一个单元格时,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedRow = indexPath;
....
[self performSegueWithIdentifier:@"OtherViewControllerSegue" sender:self];
}
并将它们带到另一个UIViewController(让我们称之为OtherViewController)。在OtherViewController中,设置所选单元格的名称。当OtherViewController被解除时,它会使用新名称更新MainViewController中的单元格:
[[[mainvc.myTableView cellForRowAtIndexPath:mainvc.selectedRow] textLabel] setText:namecell.textField.text];
[self.navigationController popViewControllerAnimated:YES];
这一切都正常,直到我有更多的细胞,而不是适合屏幕。如果屏幕上有更多的单元格(iPhone为8或iPad为16),那么这也将分别为每个第八或第十六个单元设置名称。关于我做错了什么想法?
更新
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [pointsTableView dequeueReusableCellWithIdentifier:@"myTableCell"];
return cell;
}
答案 0 :(得分:2)
您正试图在视图中存储数据(新名称)(单元格的标签)。可能发生的情况是,当您在数据源的cellForRowAtIndexPath
方法中重复使用单元格时,其中一些是已为其设置此文本的单元格,并且它仍然存在。
更好的想法是在您用作单元格信息的任何数组中进行更改,然后重新加载表格视图以使更改可见。
答案 1 :(得分:2)
这是由于细胞重用,您将模型与视图混合在一起(在MVC环境中)。
表格单元格是一种瞬态的东西,一旦它离开屏幕,当需要另一个单元格时,它会被重用(而不是创建新的单元格)。这就是dequeueReusableCellWithIdentifier:
方法的作用。
这意味着您无法在其中存储数据并期望它在以后仍然有效。在此示例中,您尝试存储表格单元格中的名称。在任何视图对象上设置属性(如标签文本)的原因纯粹是为了显示,而不是用于存储。因此,要解决此问题,您应该在模型中维护一个对象列表(例如,这可以在单独的类中或在mainvc
对象的数组中)。然后在cellForRowAtIndexPath:
中你应该每次都设置标签文本 - 即使没有标签你需要将它设置为nil或空字符串因为单元格被重复使用它可能包含上次的内容用了。
<强>更新强>
您应该使用控制器中的方法或属性设置模型中的文本,然后告诉表视图重新加载该单元格,而不是自己调用cellForRowAtIndexPath:
并设置其文本。代码可能如下所示:
// This code is in where you want to set the text from
[mainvc setText:someText forIndexPath:indexPath];
..并在主视图控制器中:
- (void)setText(NSString*)newText forIndexPath:(NSIndexPath*)indexPath
{
// Store the text in your model here...
...
// If the view is loaded, the table view should reload the cell.
if(self.isViewLoaded)
{
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
然后,表格视图将调用cellForRowAtIndexPath:
,其中文本将正确设置。这看起来有点复杂,但是当你习惯使用模型 - 视图 - 控制器设计模式时,你会发现保持每个MVC组件的工作分开就意味着你的代码更整洁,更容易理解,更少的错误,更容易更新/扩展等。
答案 2 :(得分:0)
正如我想的那样,你不应该自己打电话给cellForRowAtIndexPath
。可以调用它来创建单元格,而不是更改单元格。
例如,您可以通过委托将所需的字符串传递到第一个视图来更新表。在事件(用户设置名称)上,您可以更新所有表并将所需名称设置为单元格。
答案 3 :(得分:0)
很难确切地说出问题所在,但一种可能的解决方案可能是:
确保在cellForRowAtIndexPath中正在初始化像这样的单元格:
// Create the Cell
static NSString *recordCell = @"pickerTableCell";
cell = [tableView dequeueReusableCellWithIdentifier:recordCell];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:recordCell];
}
我知道这主要是一种记忆解决方案,但也可能会在这里凝聚。
另外,查看代码并检查如何确定重命名的单元格。您可能会意外地在多个单元格上调用重命名而没有意识到它