使用 RefreshControl 异步刷新
Posted
技术标签:
【中文标题】使用 RefreshControl 异步刷新【英文标题】:Use RefreshControl to refresh asynchronously 【发布时间】:2014-08-28 20:20:59 【问题描述】:我正在使用 AFNetworking 从 API 加载一些数据以刷新 UITableView。我希望刷新控制器能够反映这一点。
用户下拉,刷新轮出现
API 调用结束(异步调用)
API 调用返回成功或错误
UITableViewController 完成刷新,重新加载数据,刷新轮消失
所以我在自定义 UIViewController 的 viewDidLoad 中添加了一个刷新控件(我的表格视图是这个主视图的子视图),如下所示:
//Set up refresh controller
tableController = [[UITableViewController alloc]init];
tableController.view = self.subscriptionsTable;
UIRefreshControl* refresh = [[UIRefreshControl alloc]init];
[refresh addTarget:self action:@selector(loadSubscriptions) forControlEvents:UIControlEventAllEvents];
tableController.refreshControl = refresh;
然后我有我的刷新方法:(所有[connections asyncCall:self]
所做的就是通过 AFNetworking pod 向 API 发送异步调用,完成后调用我的视图控制器的已完成方法)
-(void)loadSubscriptions
updated = YES;
[connections asyncCall:self];
视图控制器完成的方法如下所示
-(void)asyncDone(id)responseObject
tableData = responseObject;
NSLog(@"Yay, I'm done!");
不幸的是,刷新控制当然是在异步调用发送的那一刻完成的,而不是在它完成的时候,这让我没有更新的数据。在异步调用实际完成之前,我怎样才能让那个东西挂起一段时间?
【问题讨论】:
【参考方案1】:您需要在异步调用开始和结束时调用beginRefreshing
和endRefreshing
。您还需要存储对 refresh
控件的引用才能执行此操作。
所以,在loadSubscriptions
和asyncDone:
:
-(void)loadSubscriptions
[self.refreshControl beginRefreshing];
updated = YES;
[connections asyncCall:self];
-(void)asyncDone(id)responseObject
tableData = responseObject;
NSLog(@"Yay, I'm done!");
[self.refreshControl endRefreshing];
注意:很多异步方法会在后台线程上调用它们的完成块,因此您可能需要将 endRefreshing
调用分派到主线程:
dispatch_async(dispatch_get_main_queue(), ^
[self.refreshControl endRefreshing];
);
【讨论】:
当我想手动触发刷新时,这会很好,但是当它们下拉时呢?这会自动启动开始刷新,调用我的 loadSubscriptions 方法,然后在完成时调用 endRefreshing,对吗? 我必须对其进行测试才能确定,但我认为手动拉动触发器本身不会触发beginRefreshing
;我认为您仍然需要手动调用它。
文档状态:控件不直接发起刷新操作。相反,它会在应该发生刷新操作时发送 UIControlEventValueChanged 事件。您必须为该事件分配一个操作方法并使用它来执行所需的任何操作。 我知道这是直接谈论刷新表格视图数据所需执行的任何操作,但我认为这也意味着您仍然需要致电begin/endRefreshing
。
看来你是对的。 AFNetworking 处理预打包的主线程上的完成调用,所以我不必担心。感谢您的教育。以上是关于使用 RefreshControl 异步刷新的主要内容,如果未能解决你的问题,请参考以下文章
在 UITableViewController 的 refreshControl 上缓慢向下滑动刷新会导致视图跳下