24

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

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

代码:

[self.tableView reloadData];
4

9 回答 9

24

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

Objective-C

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

斯威夫特 4

UIView.performWithoutAnimation {
    self.tableView.reloadData()
    self.tableView.beginUpdates()
    self.tableView.endUpdates()
}
于 2016-06-07T12:55:42.403 回答
14

如您所料,闪烁是由调用 [self.tableView reloadData]; 引起的。快速且重复,尤其是在 iOS 5.x 设备上。但是您可能不想重新加载整个表格,您只想更新表格可见单元格中的视图。

假设您要更新表格的每个单元格以反映文件正在下载时的最新下载百分比。在我的示例中调用了一个方法 [downloading:totalRead:totalExpected:],当字节下载时速度非常快。

这是应该做的......在每次小的更新时重新加载表(在这个例子中,开发人员可能依赖“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.
            }
        }
    }

编辑:文档建议相同:

调用此方法会使表视图向其数据源询问指定部分的新单元格。表格视图动画插入新单元格,因为它动画旧单元格。如果您想提醒用户指定部分的值正在更改,请调用此方法。但是,如果您只想更改指定部分的单元格中的值而不提醒用户,您可以获取这些单元格并直接设置它们的新值。

于 2013-09-07T12:27:35.150 回答
3
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:index] withRowAnimation:UITableViewRowAnimationNone];

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

您正在从表中删除行,但不是从数据源中删除。所以行被删除,但您的数据源仍然指出没有删除任何行。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];
于 2013-03-04T08:04:29.750 回答
3

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

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
于 2014-06-06T15:27:35.120 回答
2

以防万一所有其他答案都不能解决您的问题,我会发布我的解决方案。

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

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

于 2017-02-16T11:49:24.413 回答
2

试试这个:

UIView.performWithoutAnimation {
    self.tableView.reloadRows(at: [indexPath], with: .none)
}
于 2020-06-24T05:52:54.760 回答
1

请参考您的cellForRowAtIndexPath委托方法。您可能正在执行一些可能导致轻弹的操作。就我而言,我正在设置带有动画的图像视图的图像。所以每当我重新加载表格时,它都会因为那个动画而闪烁。

我删除它并为我工作..

于 2016-05-19T10:31:45.193 回答
1

我的项目中的工作是:

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

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

于 2017-02-20T14:34:46.043 回答
0

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

于 2013-03-04T08:07:14.903 回答