更新数据异步后重绘UITableView

时间:2010-02-23 23:19:58

标签: iphone uitableview xamarin.ios

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

/麦

6 个答案:

答案 0 :(得分:54)

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

<强>目标C

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

<强>夫特

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

<强> MonoTouch的

InvokeOnMainThread(() => this.TableView.ReloadData());

答案 1 :(得分:4)

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

但是,如果您的数据是异步加载的,并且在更新期间您的UITableView不可见(例如:您在另一个视图中向UITableView添加数据,之后会显示UITableView通过userinput),只需覆盖UITableViewController的{​​{1}}方法。

viewWillAppear

正面效果是,- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.tableView reloadData]; } 仅在用户真正想要查看数据时重新加载数据,而不是在添加新项目时重新加载数据。

答案 2 :(得分:2)

我猜它没有重新加载。

将单元格滚动到屏幕外时,然后......

tableView: cellForRowAtIndexPath:

...将被召唤。所以它会重新加载。

我猜UITableView变量未经过验证。

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

[self.view reloadData];

[self.tableView reloadData];

答案 3 :(得分:2)

我今天遇到了类似的问题(iOS 7.0中的故事板)。 我在UIViewController中使用表视图。当视图加载时,一切正常;所有的代表都被叫了。但是;当基础dataSource(在我的情况下,Array)被修改时;可见的表行没有得到更新。他们已更新;只有当我滚动表视图时才会这样。

尝试了一切;在主线程上调用reloadData;在ViewWillAppear中调用reload;没有用。

我发现的问题;是因为我没有在故事板中建立连接;对于带有引用Outlet的表视图。虽然设置了dataSource和delegate。 我不认为这可能是问题所在;因为一切都工作正常。

希望它有所帮助。我有一段时间可以找到它。

答案 4 :(得分:1)

快捷键4:

DispatchQueue.main.async { self.tableView.reloadData() }

答案 5 :(得分: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工作,而不仅仅是重新加载表,那么所有代码​​也应该在主队列上。

参考:A concise example使用GCD并管理后台与主线程。