UIAlertController有时会阻止UIRefreshControl隐藏
我在桌面上使用UIRefreshControl
来更新项目。最后,我展示了一个UIAlertController
来通知用户更新已完成,并更新了多少项。非常简单,一件事情可以正常工作。如果我连续刷新几次,有时甚至在关闭警报后刷新控制也不会被解除。我需要向上滑动桌子才能消失。UIAlertController有时会阻止UIRefreshControl隐藏
这是我使用的代码,所有UI的东西是很好做在主线程:
if(refreshControl.refreshing) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self refreshItems];
dispatch_async(dispatch_get_main_queue(), ^{
[refreshControl endRefreshing];
[self.tableView reload];
[self showUpdateInfo];
});
});
}
任何想法可能是什么原因?
编辑:这是我在代码中创建刷新控制(在viewDidLoad
):
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString: @"Checking for updates…"];
[refreshControl addTarget: self
action: @selector(refreshOutdatedItems)
forControlEvents: UIControlEventValueChanged];
self.refreshControl = refreshControl;
我相信它真的有与没有的tableView滚动备份UIAlertController呈现前做。我试图设置showUpdateInfo方法的延迟,似乎工作。我想当用户只需要拉一次,它将需要半秒钟来显示UIAlertController检查是否有帮助。 这里是我的代码
- (void)refreshOutdatedItems
{
NSLog(@"refresh");
if (self.refreshControl.refreshing) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (double i = 0 ; i < 100000000; i++){
};
dispatch_async(dispatch_get_main_queue(), ^{
[self.refreshControl endRefreshing];
[self performSelector:@selector(showUpdateInfo) withObject:nil afterDelay:0.5];
});
});
}
}
让我知道是否有帮助。
延迟任意时间不是一个很干净的解决方案。在我看来,通过计算两倍到一千万的数字来实现延迟也是一种破坏。
我最终什么事做,而不是与此类似伪斯威夫特:
let alert = UIAlertController(...)
present(alert, animated: true) {
refreshControl.endRefreshing()
}
它延缓调用endRefreshing(),直到提出警告。
我用斯威夫特3和实际代码PromiseKit看上去更像是这样的:
@IBAction func onRefresh() {
Repository.getNewData().then { data in
self.data = data
self.tableView.reloadData()
}.recover { error in
// Return a promise to make sure endRefreshing isn't called until the alert is presented.
return self.presentErrorAlert(message: "Some user-friendly message")
}.always {
self.refreshControl?.endRefreshing()
}
}
private func presentErrorAlert(message: String) -> Promise<Void> {
return Promise<Void> { fulfill, _ in
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true) {
fulfill()
}
}
}
这应该是公认的答案 - 以任意数量推迟是一种破解。 –
只需重置内容表视图的偏移:
- (void)endRefreshControl {
[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.bounds.size.height) animated:YES];
[self.refreshControl endRefreshing];
}
当任务完成后,调用[self endRefreshControl];
而比[self.refreshControl endRefreshing];
这似乎是Xcode中的一个bug。即使Johan Levin的解决方案有时似乎在Xcode 9.2中悬而未决。
这不完全是你要找的,但它是一个解决方法:不要使用UIAlertController。只需将您曾在UIAlertController到UIRefreshControl像这样的文字:
refreshControl?.attributedTitle = NSAttributedString(string: "Pull to reload all reminders", attributes: [NSAttributedStringKey.foregroundColor: UIColor(red: 255.0/255.0, green: 182.0/255.0, blue: 8.0/255.0, alpha: 1.0)])
你在代码中创建的UIRefreshControl或使用TableViewController财产? – Yan
请参阅我的问题中的编辑。 – Koen
我试图重现该问题。您的代码似乎按预期工作。顺便说一句,你有dispach_sync,实际上坠毁在我身上。这是故意的还是应该是dispatch_async? – Yan