gpt4 book ai didi

ios - 关闭模态呈现的 ViewController 后,UITableViewCell 不反射(reflect)更改

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:15:50 24 4
gpt4 key购买 nike

我有一个带有 TableView 的 UIViewController,用于显示“ list ”项目。这个 ViewController 还有一个按钮,可以触发 segue 以模态方式呈现另一个 UIViewController,供用户添加新的 list 项目。

所有 list 项目都存储在 CoreData 中。

新的 CoreData 实体被创建,并由 SecondViewController 存储。在点击触发关闭 SecondViewController 的按钮之前,用户可以添加任意数量的 checklist 项目。由于此 SecondViewController 是模态呈现的,因此我假设它的事件与 FirstUIViewController 根本没有任何关系。

在包含UITableViewFirstViewController中,有一个NSFetchedResultsController再次在CoreData执行获取请求并提供所有数据到 UITableView。 NSFetchedResultsController 的委托(delegate)也指向这个 FirstUIViewController

问题是,在 SecondViewController 关闭后,UITableView 似乎注意到新的 list 实体的插入,并插入了新的 UITableCell 在 UITableView 中。然而,奇怪的是,这个新插入的行没有显示正确的 cell.textlabel。仅显示标签上没有任何内容的空白 UITableViewCell

下面是我如何配置 UITableViewCell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"ChecklistCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
ChecklistItem *item = [self.fetch_controller objectAtIndexPath:indexPath];
cell.textLabel.text = item.name;
}

这是我对 NSFetchedResultsControllerDelegate 的看法

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
switch (type) {
case NSFetchedResultsChangeInsert:
NSLog(@"*** controllerDidChangeObject - NSFetchedResultsChangeInsert");
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}

强制 [self.tableView reloadData] 似乎有帮助。我知道这一点是因为我添加了一个按钮来调用此方法,并且相应地刷新和更新了单元格的标签。

因此,我尝试了这个,因为我希望它会在 SecondViewController 关闭后被调用。然而,该方法被调用是因为 Reload Data! 被记录了,但不知何故 tableView 仍然没有正确显示新添加的单元格的标签。

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self performFetch];
[self.tableView reloadData];
NSLog(@"Reload Data!");
}

我想知道这里可能出了什么问题。 self.tableViewSecondViewController 关闭后不会以某种方式重新加载。有什么建议吗?

## 编辑

好吧,更奇怪的是我在 - (void)viewDidAppear:(BOOL)animated 中尝试了 [self.tableView reloadData]。新的 tableViewCell 仍然没有正确显示它的标签;然而,等了 30 秒后,标签就神奇地弹出了!这是否意味着我的 iPhone/iPhone 模拟器需要时间思考很多?

最佳答案

解释

您的核心数据保存需要时间。如果您正在保存数据,然后立即关闭模态视图 Controller ,则您在 performFetch 函数上遇到了竞争条件。这就是为什么您会看到它在 viewWillAppear 函数中不起作用,但在您按下按钮时起作用。它有时会在 viewDidAppear 中工作,但不能保证。这取决于您是否使用模拟器,以及系统的繁忙程度。

具体建议

由于您是从核心数据中提取数据,因此我建议您使用 NSFetchedResultsController 并实现 NSFetchedResultsControllerDelegate。这些是专门为将 coreData 绑定(bind)到 UITableViewController 而设计的。它监听更改并根据这些更改立即添加、删除或更新行。

更新代码

要正确实现 NSFetchedResultsControllerDelegate,您只需从该网站复制代码:http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html

一些提示:

  1. 您需要对cellForRowAtIndexPath 的实现方式稍作更改。创建一个名为 configureCell 的新方法。这是一个陈旧的模式,因此您可以在 Apple 和其他地方的许多示例代码中找到它。
  2. 从上面网站的“典型用途”部分复制代码。您不需要实现“用户驱动的更新”。一定要设置

    self.fetchedResultsController.delegate = self;

  3. 如果您想检查此代码是否正常工作,您可以将断点或 NSLog 放入 controllerWillChangeContentcontroller:didChangeObject 中。

  4. 您无需在第一次之后再次调用 performFetch。此代码适本地监听更改和更新。
  5. 正如我一直建议大家的那样——我喜欢 MagicalRecord——所以请使用它。

配置单元格

下面的 configureCell:atIndexPath 方法由 NSFetchedResultsController 委托(delegate)调用。

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Product *product = [_fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = product.name;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Product Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}

[self configureCell:cell atIndexPath:indexPath];

return cell;
}

请在此处查看委托(delegate)实现代码。查看更新对象时如何调用 configureCell。

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {

UITableView *tableView = self.tableView;

switch(type) {

case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;

case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;

case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}

关于ios - 关闭模态呈现的 ViewController 后,UITableViewCell 不反射(reflect)更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14942300/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com