用新数据重新加载uitableview导致闪烁

时间:2013-03-04 07:55:05

标签: iphone ios ios5 uitableview

我添加了一个无限滚动功能,并意识到每当我重新加载uitableview时,视图都会闪烁......我不知道如何修复此时的闪烁。请帮忙,谢谢!

我确实看到了一个非常相似的问题,但没有解决方案。我尝试了作者发布的那个,但它不起作用:“从父视图中删除tableview,重新加载数据,将表视图放回父视图”(UITableView reloadData - how to stop flicker

代码:         [self.tableView reloadData];

10 个答案:

答案 0 :(得分:12)

正如您所猜测的那样,调用[self.tableView reloadData]会导致闪烁;快速反复,特别是在iOS 5.x设备上。但是您可能不想重新加载整个表,只想更新表中可见单元格中的视图。

假设您要更新表格的每个单元格以反映正在下载文件的最新下载量%。在我的例子中调用了一个方法[downloads:totalRead:totalExpected:],在下载字节时非常快。

这就是 NOT 要执行的操作......在每次小更新时重新加载表(在此示例中,开发人员可能依赖“cellForRowAtIndexPath”或“willDisplayCell”方法执行所有更新可见细胞):

    - (void)downloading:(PPFile *)file totalRead:(long long)read totalExpected:(long long)expected {
        // Bad! Causes flickering when rapidly executed:
        [self.tableView reloadData];
    }

以下是更好的解决方案。当需要更新单元格的视图时,通过仅从表中获取可见单元格来查找该单元格,然后直接更新该单元格的视图而不重新加载表格:

    - (void)downloading:(PPFile *)file totalRead:(long long)read totalExpected:(long long)expected {
        NSArray *cells = [self.tableView visibleCells];

        for(MYCellView *cell in cells) {
            if(cell.fileReference == file) {
                // Update your cell's view here.
            }
        }
    }

编辑: docs推荐相同的内容:

  

调用此方法会导致表视图询问其数据源   指定部分的新单元格。表格视图动画了   插入新细胞,因为它将旧细胞动画化。叫这个   方法如果要提醒用户指定的值   部分正在改变。 但是,如果您只想更改值   指定部分的单元格没有提醒用户,你可以得到   这些单元格并直接设置其新值。

答案 1 :(得分:12)

下面的代码对我来说就像一个魅力!

<强>目标C

[UIView performWithoutAnimation:^{
   [self.tableview reloadData];
   [self.tableview beginUpdates];
   [self.tableview endUpdates];
}];

Swift 4

UIView.performWithoutAnimation {
    self.tableView.reloadData()
    self.tableView.beginUpdates()
    self.tableView.endUpdates()
}

答案 2 :(得分:3)

    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:index] withRowAnimation:UITableViewRowAnimationNone];

每当您在更新中删除或添加表行时,表视图会重新加载并根据动画定位的单元格向数据源询问行数。

您正在从表中删除行而不是从datasource删除行。所以删除行但您的数据源仍然指出没有行被删除..20个对象仍然存在。您的数据源将类似于

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return MyDataModel.count; // 
}

所以你需要删除或添加数据源中的新数据......就像这样

   NSIndexPath *index = [NSIndexPath indexPathForRow:i inSection:0];
   [MyDataModel removeObjectAtIndex:index.row];
   [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:index] withRowAnimation:UITableViewRowAnimationNone];

答案 3 :(得分:3)

为什么不简单地调用reloadSections方法而不是[self.tableView reloadData];

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];

答案 4 :(得分:1)

参考您的cellForRowAtIndexPath委托方法。您可能正在进行一些可能导致轻弹的操作。就我而言,我正在设置带有动画的图像视图的图像。因此,每当我重新加载表时,由于该动画,它都会闪烁。

我删除它并为我工作..

答案 5 :(得分:0)

你正在使用deleteRowsAtIndex吗?如果重新加载表,则调用所有表委托方法。 我认为删除所有行需要时间,然后重新加载。 只需使用重载方法并尝试。

答案 6 :(得分:0)

如果所有其他答案都无法解决您的问题,我会发布我的解决方案。

如果您对每个部分使用估计高度 estimatedSectionHeaderHeightestimatedRowHeight-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath以及动态行数(例如可扩展的两级tableView)

你应该停止使用它并实现-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath以返回正确的高度。

答案 7 :(得分:0)

我的项目中有哪些工作:

UIView.PerformWithoutAnimation(() =>
{
tableView.ReloadData();
tableView.LayoutIfNeeded();
});

(它在c#xamarin中......但与目标c的快速相同)

答案 8 :(得分:0)

您将其添加到单元格了吗?

cell.selected = YES;

如果您确实不想让屏幕闪烁,则应添加以下内容:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

希望是有帮助的。

答案 9 :(得分:0)

是的,尝试此操作,您就完成了!

UIView.performWithoutAnimation {
  self.tableView.reloadRows(at: [indexPath], with: .none)

}

编码愉快!