ios 使用新数据重新加载 uitableview 导致闪烁
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15196927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
reload uitableview with new data caused flickering
提问by trillions
I added an infinite scrolling feature and realized that whenever I reload the uitableview, the view flickers..I am not sure how to fix the flickering at this point. Please help, thanks!
我添加了一个无限滚动功能,并意识到每当我重新加载 uitableview 时,视图都会闪烁......我不知道此时如何修复闪烁。请帮忙,谢谢!
I did see a very similar question, but no solution to it. I tried the one the author posted, but it doesn't not work: "remove the tableview from parent view, reload data, put table view back into parent view" (UITableView reloadData - how to stop flicker)
我确实看到了一个非常相似的问题,但没有解决方案。我尝试了作者发布的那个,但它不起作用:“从父视图中删除表视图,重新加载数据,将表视图放回父视图”(UITableView reloadData - 如何停止闪烁)
Code:
代码:
[self.tableView reloadData];
采纳答案by Moss
As you have guessed, flickering is caused by calling [self.tableView reloadData]; rapidly and repeatedly, especially on iOS 5.x devices. But you probably do not want to reload the entire table, you want to update just the view within the visible cells of the table.
你已经猜到了,闪烁是因为调用了[self.tableView reloadData]; 快速且反复,尤其是在 iOS 5.x 设备上。但您可能不想重新加载整个表格,而只想更新表格可见单元格内的视图。
Let's say you want to update each cell of a table to reflect the latest download % as a file is downloading. A method [downloading:totalRead:totalExpected:] gets called in my example, extremely rapidly as bytes are downloading.
假设您要更新表格的每个单元格以反映文件下载时的最新下载百分比。一个方法 [downloading:totalRead:totalExpected:] 在我的例子中被调用,随着字节的下载速度非常快。
This is what NOTto do... reload the table on every little update (in this example, the developer may rely on "cellForRowAtIndexPath" or "willDisplayCell" methods perform the updating of all the visible cells):
这是不应该做的...在每次小的更新时重新加载表(在这个例子中,开发人员可能依赖“cellForRowAtIndexPath”或“willDisplayCell”方法来执行所有可见单元格的更新):
- (void)downloading:(PPFile *)file totalRead:(long long)read totalExpected:(long long)expected {
// Bad! Causes flickering when rapidly executed:
[self.tableView reloadData];
}
The following is a better solution. When a cell's view needs to be updated, find that cell by grabbing only the visible cells from the table, and then update that cell's view directly without reloading the table:
下面是一个更好的解决方案。当一个单元格的视图需要更新时,通过只抓取表格中可见的单元格来找到该单元格,然后直接更新该单元格的视图,而无需重新加载表格:
- (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.
}
}
}
EDIT:The docsrecommend the same:
编辑:该文档建议相同:
Calling this method causes the table view to ask its data source for new cells for the specified sections. The table view animates the insertion of new cells in as it animates the old cells out. Call this method if you want to alert the user that the values of the designated sections are changing. If, however, you just want to change values in cells of the specified sections without alerting the user, you can get those cells and directly set their new values.
调用此方法会导致表视图向其数据源询问指定部分的新单元格。表视图动画插入新单元格,因为它动画旧单元格。如果您想提醒用户指定部分的值正在更改,请调用此方法。但是,如果您只想在不通知用户的情况下更改指定部分的单元格中的值,则可以获取这些单元格并直接设置它们的新值。
回答by Shaunak
Below code worked for me like a charm!
下面的代码对我很有用!
Objective-C
目标-C
[UIView performWithoutAnimation:^{
[self.tableview reloadData];
[self.tableview beginUpdates];
[self.tableview endUpdates];
}];
Swift 4
斯威夫特 4
UIView.performWithoutAnimation {
self.tableView.reloadData()
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
回答by Zoeb S
Why don't you simply call reloadSections method instead of [self.tableView reloadData];
为什么不简单地调用 reloadSections 方法而不是 [self.tableView reloadData];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
回答by Shubhank
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:index] withRowAnimation:UITableViewRowAnimationNone];
whenever you remove or add a table row in updates..the table view reloads and ask the datasource for the number of rows based on which cell is animated to position.
每当您在更新中删除或添加表格行时..表格视图会重新加载并根据动画定位的单元格向数据源询问行数。
you are removing row from table but not from datasource..so rows are deleted but your datasource still points out that no row is deleted..20 objects are still there. your data source will be something like
您正在从表中删除行而不是从数据源中删除行..所以行被删除但您的数据源仍然指出没有行被删除..20 个对象仍然存在。您的数据源将类似于
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return MyDataModel.count; //
}
so you need to remove or add new data in datasource also..something like this
所以你还需要在数据源中删除或添加新数据......像这样
NSIndexPath *index = [NSIndexPath indexPathForRow:i inSection:0];
[MyDataModel removeObjectAtIndex:index.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:index] withRowAnimation:UITableViewRowAnimationNone];
回答by NSPratik
Refer your cellForRowAtIndexPath
delegate method. You might be doing some operation that might cause a flick. In my case, I was setting an image of a image view with animation. So whenever I reload the table, it was flickering due to that animation.
请参阅您的cellForRowAtIndexPath
委托方法。您可能正在执行一些可能导致轻弹的操作。就我而言,我正在设置带有动画的图像视图的图像。因此,每当我重新加载表格时,它都会由于该动画而闪烁。
I removed it and worked for me..
我删除了它并为我工作..
回答by ooops
Just in case all other answers do not solve your problem, I post my solution.
以防万一所有其他答案都不能解决您的问题,我会发布我的解决方案。
If you use estimated heightestimatedSectionHeaderHeight
or estimatedRowHeight
or -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
, and with dynamic row countfor each section (e.g. expandable two level tableView)
如果您使用估计高度estimatedSectionHeaderHeight
或estimatedRowHeight
或-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
,并且每个部分的动态行数(例如可扩展的两级tableView)
you should stop using this and implement -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
to return the correct height.
你应该停止使用它并实现-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
返回正确的高度。
回答by gal danay
what work in my project was :
我的项目中的工作是:
UIView.PerformWithoutAnimation(() =>
{
tableView.ReloadData();
tableView.LayoutIfNeeded();
});
(it's in c# xamarin...but the same with swift of objective c)
(它在 c# xamarin 中……但与目标 c 的 swift 相同)
回答by Durgaprasad
y you are using deleteRowsAtIndex? If you reload table all table delegate methods are called. I think it is taking time to delete all rows and then again reload. Just use reload method and try.
您正在使用 deleteRowsAtIndex 吗?如果您重新加载表,则会调用所有表委托方法。我认为删除所有行然后再次重新加载需要时间。只需使用重新加载方法并尝试。