更改单元格中的数据后,UITableView 中的自定义单元格将无法正确重新加载
Posted
技术标签:
【中文标题】更改单元格中的数据后,UITableView 中的自定义单元格将无法正确重新加载【英文标题】:Custom Cell in UITableView won't reload correctly after data in the cell is changed 【发布时间】:2014-03-02 13:40:38 【问题描述】:我在UITableView
中创建了一个自定义单元格。样式设置为自定义。标识符设置为 customCell。附件设置为详细信息。表视图内容设置为动态原型。
该表已加载来自核心数据的数据,并且在首次出现时显示得非常完美。当用户点击单元格中的详细信息图标时,会出现一个新视图,以便用户可以编辑单元格中的数据并将其保存到核心数据中。当用户完成编辑并点击保存按钮时,视图返回到UITableView
,但刚刚编辑的单元格显示为“基本”单元格,而不是 customCell。如果我点击单元格,它会突出显示并且自定义单元格内容出现在基本单元格内容之上。
我似乎无法解决这个问题。任何人都可以提出一些建议吗?
这是prepareForSegue
发送到编辑视图控制器的部分:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell*)sender
if ([[segue identifier]isEqualToString:@"editPunchItemSegue"])
// DEFINE SEGUE DESTINATION
UINavigationController *navigationController = segue.destinationViewController;
EditPunchItemViewController *editPunchItemViewController = (EditPunchItemViewController*)navigationController.topViewController;
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
Punchitem *editPunchItem = (Punchitem*)[self.fetchedResultsController objectAtIndexPath:indexPath];
editPunchItemViewController.editPunchitem = editPunchItem;
现在,在编辑核心数据的目标 View Controller 中,这里是 saveButtonPressed 方法的一部分:
if ([_editSaveButton.title isEqualToString:@"Save"])
NSLog(@"Save Button has been PRESSED");
editPunchitem.punchitemRoomNumber = _editPunchitemRoomNumberField.text;
editPunchitem.punchitemDescription = _editPunchitemDescriptionField.text;
editPunchitem.punchitemLocation = _editPunchitemLocationField.text;
editPunchitem.punchitemRoomName = _editPunchitemRoomNameField.text;
editPunchitem.punchitemDate = _editPunchitemDateField.text;
// SAVE TO MANAGE OBJECT CONTEXT!
[super saveAndDismiss];
有什么建议吗?
这是我在 TableViewController 中的 cellForRowAtIndex
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
static NSString *CellIdentifier = @"customCell";
// USING CUSTOM PROTOTYPE CELL:
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// Configure the cell...
Punchitem *punchitem = [self.fetchedResultsController objectAtIndexPath:indexPath];
// USING CUSTOM PROTOTYPE CELL:
cell.cellLocationLabel.text = punchitem.punchitemLocation;
cell.cellDescriptionLabel.text = punchitem.punchitemDescription;
cell.cellRoomNameLabel.text = punchitem.punchitemRoomName;
return cell;
保存和关闭是子类的一部分。方法如下:
-(void) saveAndDismiss
NSError *error = nil;
if ([self.managedObjectContext hasChanges])
if (![self.managedObjectContext save:&error]) //SAVE FAILED
NSLog(@"YOUR SAVE FAILED! %@", [error localizedDescription]);
else
NSLog(@"SAVE SUCCEEDED!");
[self dismissViewControllerAnimated:YES completion:nil];
【问题讨论】:
save 和 dissmiss 是做什么的,请显示 cellAtRowIndex,看起来有些东西正在覆盖你的故事板 我刚刚在我的原始帖子中添加了我的 cellForRowAtIndex 尝试使用xib原型单元。 在聊天中找到了非常好的解决方案。 【参考方案1】:当您从 EditPunchItemViewController 回来时,您是否尝试过重新加载表格?
放入主视图控制器:
- (void)viewWillAppear:(BOOL)animated
if (self.tableView)
[self.tableView reloadData];
【讨论】:
是的,我的 TableViewController 的 viewWillAppear 中确实有这一行。不幸的是,它没有帮助。【参考方案2】:你有过这样的事情
[self.tableView beginUpdates];
如果是,你确定在完成后调用这个
[self.tableView endUpdates];
大多数时候我们将它与 NSFetchedResultsController 一起使用...
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
[self.tableView beginUpdates];
...
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
[self.tableView endUpdates];
【讨论】:
是的,谢谢你的建议,但我的代码中已经包含了这两种方法。【参考方案3】:最后一个选项,你必须条件调试...
全部在您的主视图控制器中:
1) 添加属性
@property (strong,nonatomic) NSIndexPath *DEBUGindexPath;
2) 在
中设置DEBUGindexPath-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell*)sender
if ([[segue identifier]isEqualToString:@"editPunchItemSegue"])
...
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
DEBUGindexPath = indexPath;
...
3) 在中添加断点
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
编辑断点设置条件:
(self.DEBUGindexPath.row == indexPath.row) && (self.DEBUGindexPath.section == indexPath.section)
不要设置自动继续...
好的,现在运行您的应用程序。当您从 EditPunchItemViewController 返回时,断点应仅针对选定的行触发。一步一步去检查你是否能找到一些东西
【讨论】:
【参考方案4】:视图返回到 UITableView,但刚刚编辑的单元格显示为“基本”单元格,而不是 customCell。
仔细看cellForRowAtIndexPath
,条件如下:
//USING CUSTOM PROTOTYPE CELL:
CustomTableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[CustomTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
当单元格为 nil 时,您将其样式设置为 UITableViewCellStyleDefault
,但您忘记通过代码设置其附件类型。
因此,请确保在 if 语句中设置其附件类型,如下所示:
//USING CUSTOM PROTOTYPE CELL:
CustomTableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[CustomTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
//Set accessory to Detail
cell.accessoryType = UITableViewCellAccessoryDetailButton;
这是样式的完整列表:
typedef enum : NSInteger
UITableViewCellAccessoryNone,
UITableViewCellAccessoryDisclosureIndicator,
UITableViewCellAccessoryDetailDisclosureButton,
UITableViewCellAccessoryCheckmark,
UITableViewCellAccessoryDetailButton
UITableViewCellAccessoryType;
【讨论】:
我不明白。我正在使用自定义单元格。当表格视图加载时,我得到一个基本视图而不是我的自定义视图。我在哪里添加行 cell.accessoryType = UITableViewCellAccessoryDetailButton 以确保出现自定义单元格而不是基本单元格?我应该使用 UITableViewCellStyleDefault 以外的东西吗? @Jupiter869 对不起,我不是很清楚,请参阅我的编辑 不幸的是,这没有效果。当我从 EditView 返回 TableView 时,单元格显示为“基本”单元格,其中包含一行数据,而不是我在情节提要中设置的“customCell”。如果我单击单元格,它会突出显示,并且“基本”和“自定义单元”都出现在彼此的顶部。看起来好像“基本”单元位于“自定义单元”的顶部。这令人困惑和非常沮丧对我来说。 这张照片显示了第一次加载时的 tableView:imgur.com/sPoazwi - 下一张照片显示了第二个单元格被编辑后的 tableView。请注意,单元格显示基本单元格格式:imgur.com/TSFct3J - 最后一张图片显示了当我单击第二个单元格时发生的情况。 customCell 出现在基本单元格的顶部:imgur.com/uHtSoon @Jupiter869 你正在使用原型单元?以上是关于更改单元格中的数据后,UITableView 中的自定义单元格将无法正确重新加载的主要内容,如果未能解决你的问题,请参考以下文章
自定义 UITableView 单元格中的 UILabel 未随核心数据更改而更新
滚动 UITableView 时自定义单元格中的 UITextField 文本正在更改