自 iOS 11 后 RefreshControl 刷新后的粘性 UINavigationbar
Sticky UINavigationbar after RefreshControl refreshed since iOS 11
我们有一个使用两个导航层次结构的模块化应用程序,因此两个堆叠的导航栏......
有时,当拉动 refreshcontrol 时,导航栏保持很大并且在完成刷新后不会恢复到正常大小。我只能猜测,在哪种情况下它会退回,而在哪些情况下不会……可视化调试器显示,使用此 space 的视图是 _UINavigationBarLargeTitleView
。在 viewDidLoad
中,self.navigationController.navigationBar.prefersLargeTitles
设置为 NO
。
通过以下方式在 viewDidLoad
中添加 RefreshControl:
self.refreshControl = [RefreshControl new];
一些我已经尝试过的东西:
- 将 tableViews
contentOffset
设置为 (0,-1)。
- 将 prefersLargeTitles 设置为
YES
,然后设置为 NO
。
- 设置 UINavigationControllers self.navigationItem.
largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
- 记录 UIRefreshControl 的不同状态:粘性视图和工作视图产生相同的日志记录。
有谁知道是什么导致了这个问题?正如我所说,我什至不确定这到底是什么时候发生的,什么时候不发生的……
看起来这是 Apple 的一个错误。
试试这个
tableView.refreshControl?.endRefreshing()
//Because of a bug in iOS11 that leaves empty placeholder for refresh control
navigationController?.navigationBar.setNeedsLayout()
navigationController?.navigationBar.layoutIfNeeded()
也试试
navigationController?.navigationBar.appearance().isTranslucent = true
好像只有navigationBar.isTranslucent == false
才会出现这个问题。我需要此设置才能获得真正的 100% 黑色导航栏。
暂时我使用这个非常肮脏的 hack,灵感来自 Exception 的答案:
self.refreshControl?.endRefreshing()
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.isTranslucent = false
}
绝对是 Apple 的错误。除了以下解决方法外,无法使其正常工作。
tableView.reloadData {
// Slightly scroll up, moving the navigation bar back to place
self.tableView.setContentOffset(CGPoint(x: 0, y: -0.3), animated: false)
}
注意:必须在 tableView 重新加载并且没有动画之后。
此外,如果标题或第一个单元格变形,您可以添加此行:
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
应该有助于return标题或单元格处于正常状态。完整代码可能如下所示:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.navigationController?.navigationBar.isTranslucent = true
if self.refreshControl!.isRefreshing {
self.refreshControl!.endRefreshing()
}
self.navigationController?.navigationBar.isTranslucent = false
self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
我们有一个使用两个导航层次结构的模块化应用程序,因此两个堆叠的导航栏......
有时,当拉动 refreshcontrol 时,导航栏保持很大并且在完成刷新后不会恢复到正常大小。我只能猜测,在哪种情况下它会退回,而在哪些情况下不会……可视化调试器显示,使用此 space 的视图是 _UINavigationBarLargeTitleView
。在 viewDidLoad
中,self.navigationController.navigationBar.prefersLargeTitles
设置为 NO
。
通过以下方式在 viewDidLoad
中添加 RefreshControl:
self.refreshControl = [RefreshControl new];
一些我已经尝试过的东西:
- 将 tableViews
contentOffset
设置为 (0,-1)。 - 将 prefersLargeTitles 设置为
YES
,然后设置为NO
。 - 设置 UINavigationControllers self.navigationItem.
largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
- 记录 UIRefreshControl 的不同状态:粘性视图和工作视图产生相同的日志记录。
有谁知道是什么导致了这个问题?正如我所说,我什至不确定这到底是什么时候发生的,什么时候不发生的……
看起来这是 Apple 的一个错误。 试试这个
tableView.refreshControl?.endRefreshing()
//Because of a bug in iOS11 that leaves empty placeholder for refresh control
navigationController?.navigationBar.setNeedsLayout()
navigationController?.navigationBar.layoutIfNeeded()
也试试
navigationController?.navigationBar.appearance().isTranslucent = true
好像只有navigationBar.isTranslucent == false
才会出现这个问题。我需要此设置才能获得真正的 100% 黑色导航栏。
暂时我使用这个非常肮脏的 hack,灵感来自 Exception 的答案:
self.refreshControl?.endRefreshing()
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.isTranslucent = false
}
绝对是 Apple 的错误。除了以下解决方法外,无法使其正常工作。
tableView.reloadData {
// Slightly scroll up, moving the navigation bar back to place
self.tableView.setContentOffset(CGPoint(x: 0, y: -0.3), animated: false)
}
注意:必须在 tableView 重新加载并且没有动画之后。
此外,如果标题或第一个单元格变形,您可以添加此行:
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
应该有助于return标题或单元格处于正常状态。完整代码可能如下所示:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.navigationController?.navigationBar.isTranslucent = true
if self.refreshControl!.isRefreshing {
self.refreshControl!.endRefreshing()
}
self.navigationController?.navigationBar.isTranslucent = false
self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}