在不使用reloadData的情况下动态更新UITableView的各个部分

时间:2012-09-17 01:34:00

标签: objective-c ios uitableview

首先,如果有人回答,我真诚地道歉。我一直在和这个争斗太久了。我会感激任何帮助。

我正在开发一个应用程序,它从不同的Web源异步获取数据并将其解析为由我的主模型处理的对象。此模型为UITableView提供信息。当接收和解析数据时,我需要修改表视图中的节和行数。我首先接收决定部分数量的数据,然后是异步数据,它修改每个部分中的行数及其内容。我已经设置了表视图数据源。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.

    return [self.sijainti.pysakit count];

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    //if ([[[self.sijainti.pysakit objectAtIndex:section] ajatStr] count] == 0) return 1;
    NSLog(@"ajatStr of section: %d  count: %d",section, [[[self.sijainti.pysakit objectAtIndex:section] ajatStr] count]);
    return [[[self.sijainti.pysakit objectAtIndex:section] ajatStr] count];
}

对象名称是芬兰语(长篇故事)。 numberOfRowsInSection的第二行被注释以简化调试。现在,因为数据是动态的,所以当我准备好显示数据时我需要更新界面,或者用户不知道它直到它们滚动并再次返回。我有一个方法:

- (void)updateRowWithCell:(SCPysakki *)valmisPysakki {
    if (!valmisPysakki.isInArray) return;

    int section = [self.sijainti.pysakit indexOfObject:valmisPysakki];

    [self.tableView beginUpdates];
    NSIndexSet *sectionSet = [NSIndexSet indexSetWithIndex:section];
    [self.tableView reloadSections:sectionSet withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];
}

只有在已知部分数量后才会调用此方法。由于效率和动画,我不想使用reloadData。我以前有这个设置,所以我只有行,只是在行内绘制行。但是一旦行变得比iphone屏幕更高,它变得非常不清楚,因为你看不到标题。所以我制作了它们的部分,并且行绘制了真实的行。然后我突然遇到了一个问题。 reloadRowsAtIndexPaths:withRowAnimation:工作得很好但是使用reloadSections:withRowAnimation:给了我这个例外:

  

* 断言失败 - [UITableView _endCellAnimationsWithContext:],/ SourceCache / UIKit_Sim / UIKit-1914.84 / UITableView.m:1037

     

2012-09-17 04:11:27.769 pysappi [2351:f803] * 由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第1部分中的无效行数更新后的现有部分中包含的行数(1)必须等于更新前的该部分中包含的行数(0),加上或减去从该部分插入或删除的行数(0)插入,0删除)并加上或减去移入或移出该部分的行数(0移入,0移出)。'

我能够通过将[self.tableView endUpdate]和[self.tableView endUpdate]添加到update方法来消除这种情况。但是哦,不,这只有在我:

时才有效
  1. 在接收到决定部分数量的数据后使用reloadData(这反过来会缩短tableview,以便在每次更新后整个更新后用户位于表顶部。我宁愿动态更新部分,不使用reloadData,除非删除Sections,但如果我尝试这样做,我会再次获得异常。)

  2. 在仅接收一行数据后更新这些部分(因此,如果我在收到所有数据后尝试更新该部分中的所有行,则会再次获得该异常。)

    < / LI>

    现在这会产生一种无法创建良好用户界面的情况。我确信底层问题没有通过开始和结束更新调用来解决,但这只是因为一些非常奇怪的原因而修复它。

    我还尝试使用insertRowsAtIndexPaths手动添加行:并手动更新它们,但这会返回完全相同的错误。在长时间的调试过程中,我已经能够确定在调用cellForRowAtIndexPath:之后此异常上升,并且它返回更新期间添加的新行之一的单元格,即使numberOfRowsInSection应该更新了行数。我还假设,如果这些情况适用,这就是开始和结束更新方法使行更新起作用的原因。

    除了我上面解释的以外,唯一有效的方法是仅使用reloadData,但考虑到更新量,这几乎是不可能的。

    这比我想象的要长得多,早上4点30分。由于这个例外,这不是我第一次这么晚。如果您需要更多信息,请询问。提前谢谢。

1 个答案:

答案 0 :(得分:0)

(在评论中回答。转换为社区wiki答案。见Question with no answers, but issue solved in the comments (or extended in chat)

@deleted_user写道:

  

更新后的现有部分中包含的行数(1)必须等于更新前的该部分中包含的行数(0), - 您有一个零行的部分并使用行 - 可可没有看到它作为插入而失败了