24

我有一个 UITableview,我用数据异步加载,所以 tableview 可能会出现没有数据。
我已经厌倦了 ReloadData 方法,但表格视图仍然是空的,直到我滚动表格视图,突然出现数据。
当我将表格视图加载为详细视图并在项目之间切换时,也会发生同样的事情,之前的项目数据首先出现,一旦我在表格视图中滚动,它就会显示正确的数据。
我的猜测是 ReloadData 方法工作得很好,但我需要以某种方式重绘 tableview,关于如何解决这个问题的任何建议?

/吉米

4

6 回答 6

56

您说您正在异步填充内容,但是您是否在主线程的上下文中调用了 reloadData ?(而不是通过填充内容的线程)

Objective-C

[yourUITableView performSelectorOnMainThread:@selector(reloadData)
                                  withObject:nil 
                               waitUntilDone:NO];

迅速

dispatch_async(dispatch_get_main_queue(), { self.tableView.reloadData() })

单触式

InvokeOnMainThread(() => this.TableView.ReloadData());
于 2010-02-24T10:37:54.660 回答
4

当您的视图当前对用户可见时,Yonels 的回答是完美的(例如:用户按下填充您的重新加载按钮UITableView。)

但是,如果您的数据是异步加载的并且您UITableView在更新期间不可见(例如:您将数据添加到UITableView另一个视图中并且UITableView稍后由用户输入显示),只需覆盖UITableViewController'viewWillAppear方法。

- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.tableView reloadData];
}

积极的影响是,您UITableView只在用户真正想要查看它时重新加载它的数据,而不是在添加新项目时。

于 2013-01-07T20:42:46.710 回答
2

估计没有重载。

当您将单元格滚动到屏幕外时,然后……</p>

tableView: cellForRowAtIndexPath:

......将被调用。所以它会被重新加载。

我猜 UITableView 变量没有经过验证。

如果你使用 UITableView 作为主视图,你可以试试这个。

[self.view reloadData];

或者

[self.tableView reloadData];

于 2010-02-24T08:28:25.570 回答
2

我今天遇到了类似的问题(iOS 7.0 中的故事板)。我在 UIViewController 中使用表视图。加载视图时,一切正常;所有的代表都被召唤了。然而;当底层数据源(在我的例子中,数组)被修改时;可见表行没有得到更新。它们被更新了;只有当我滚动表格视图时。

什么都试过了;在主线程上调用 reloadData;在 ViewWillAppear 中调用 reload;没有任何效果。

我发现的问题;是我没有在情节提要中建立联系;对于具有引用 Outlet 的表视图。尽管设置了数据源和委托。我不认为这可能是问题所在。因为一开始一切都很好。

希望它可以帮助某人。我花了一些糟糕的时间才发现这一点。

于 2014-02-08T06:20:44.897 回答
1

斯威夫特 4:

DispatchQueue.main.async { self.tableView.reloadData() }
于 2019-01-20T21:16:33.493 回答
0

在有些天真地复制了 yonel 的解决方案并称其为好之后,我意识到调用 performSelectorOnMainThread:withObject:waitUntilDone:解决了症状,但没有解决问题。更大的问题是您仍在异步或后台线程的上下文中进行 UI 更新。

这就是我的代码的样子:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL);
dispatch_async(queue, ^{

  // Make API call
  // Retrieve data, parse JSON, update local properties
  // Make a call to reload table data

});

什么时候应该是这样的:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL);
dispatch_async(queue, ^{

  // Make API call
  // Retrieve data, parse JSON, update local properties

  dispatch_async(dispatch_get_main_queue(), ^{
    // Now make the call to reload data and make any other UI updates
    [self.tableView reloadData]
  });

});

如果您唯一需要做的就是调用[self.tableView reloadData]它可能没问题,performSelectorOnMainThread:withObject:waitUntilDone:因为它实现了相同的目标,但您还应该认识到大局中正在发生的事情。此外,如果您正在做的 UI 工作不仅仅是重新加载表格,那么所有这些代码也应该放在主队列中。

参考:使用 GCD 和管理后台与主线程的简明示例

于 2014-03-05T23:44:57.157 回答