更改单元格中的数据后,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 = UITableViewCellAccessoryDe​​tailButton 以确保出现自定义单元格而不是基本单元格?我应该使用 UITableViewCellStyleDefault 以外的东西吗? @Jupiter869 对不起,我不是很清楚,请参阅我的编辑 不幸的是,这没有效果。当我从 EditView 返回 TableView 时,单元格显示为“基本”单元格,其中包含一行数据,而不是我在情节提要中设置的“customCell”。如果我单击单元格,它会突出显示,并且“基本”和“自定义单元”都出现在彼此的顶部。看起来好像“基本”单元位于“自定义单元”的顶部。这令人困惑和非常沮丧对我来说。 这张照片显示了第一次加载时的 tableView:imgur.com/sPoazwi - 下一张照片显示了第二个单元格被编辑后的 ​​tableView。请注意,单元格显示基本单元格格式:imgur.com/TSFct3J - 最后一张图片显示了当我单击第二个单元格时发生的情况。 customCell 出现在基本单元格的顶部:imgur.com/uHtSoon @Jupiter869 你正在使用原型单元?

以上是关于更改单元格中的数据后,UITableView 中的自定义单元格将无法正确重新加载的主要内容,如果未能解决你的问题,请参考以下文章

自定义 UITableView 单元格中的 UILabel 未随核心数据更改而更新

滚动 UITableView 时自定义单元格中的 UITextField 文本正在更改

检测哪个按钮需要更改单元格中的文本

问:如何更改 UITableView 中的单元格大小,以显示所有标签?

UITableView 单元格中的可重用单元格存在问题

从已知按钮标签更改自定义单元格中的特定按钮标题