UIScrollView + LargeTitle (iOS 11) - 滚动到顶部并显示大标题
Posted
技术标签:
【中文标题】UIScrollView + LargeTitle (iOS 11) - 滚动到顶部并显示大标题【英文标题】:UIScrollView + LargeTitle (iOS 11) - scroll to top and reveal the large title 【发布时间】:2018-08-17 10:01:51 【问题描述】:我使用以下代码滚动到 UICollectionView 的顶部:
scrollView.scrollRectToVisible(CGRect(origin: .zero, size: CGSize(width: 1, height: 1)), animated: true)
但是,在 ios 11 和 12 上,scrollView 仅滚动到顶部,而不会显示UINavigationBar
的大标题(当prefersLargeTitle
已设置为true
。)
如下所示:
我想要达到的结果:
【问题讨论】:
你的标题是不是变大了?? 没错,滚动视图滚动到顶部后它不会变大。虽然,我可以通过手动拖动滚动视图来恢复它。 我认为这是您无法以编程方式处理此问题的属性。从开发人员端,您只能无法使用此属性,并且当用户上下滚动时,标题将相应放大。 【参考方案1】:它按设计工作,您正在滚动到位置 y = 0
,将您的 controller
分配为 UIScrollView
代表并打印出滚动偏移:
override func scrollViewDidScroll(_ scrollView: UIScrollView)
print(scrollView.contentOffset)
您将看到何时显示大标题并移动滚动视图 a 但它会跳回大标题它不会打印 (0.0, 0.0)
但 (0.0, -64.0)
或 (0.0, -116.0)
- 这是与 @ 相同的值987654328@,所以如果你想向上滚动并显示大标题,你应该这样做:
scrollView.scrollRectToVisible(CGRect(x: 0, y: -64, width: 1, height: 1), animated: true)
【讨论】:
-64
效果最好,尽管从adjustedContentInset.top
派生的值更大并且滚动视图“过度滚动”。
这是 Xamarin.iOS 中的有效解决方案,非常感谢您! UICollectionView 的任何解决方案,因为我似乎有同样的问题【参考方案2】:
您不想使用任何“魔法值”(在当前接受的答案中为 -64)。这些可能会改变(另外,-64 也不正确)。
更好的解决方案是观察 SafeAreaInsets 的变化并保存最大的顶部插图。然后在 setContentOffset 方法中使用这个值。像这样:
class CollectioViewController: UIViewController
var biggestTopSafeAreaInset: CGFloat = 0
override func viewSafeAreaInsetsDidChange()
super.viewSafeAreaInsetsDidChange()
self.biggestTopSafeAreaInset = max(ui.safeAreaInsets.top, biggestTopSafeAreaInset)
func scrollToTop(animated: Bool)
ui.scrollView.setContentOffset(CGPoint(x: 0, y: -biggestTopSafeAreaInset), animated: animated)
【讨论】:
接受的答案 (-64) 适用于特定问题,但此答案适用于多种不同的情况。我更喜欢此作为最佳答案。【参考方案3】:似乎使用负内容偏移量是可行的方法。
我真的很喜欢 Demosthese 的想法,以跟踪最大的顶部插图。 但是,这种方法存在一个问题。 有时无法显示大标题,例如,当 iPhone 处于横向模式时。
如果在设备旋转到横向后使用此方法,则表格的偏移量将太大,因为导航栏中不显示大标题。
这项技术的一个改进是仅在导航栏可以显示大标题时才考虑最大的TopSafeAreaInset。 现在的问题是了解导航栏何时可以显示大标题。 我在不同的设备上做了一些测试,当垂直尺寸类紧凑时,似乎没有显示大标题。
因此,Demosthese 解决方案可以通过这种方式进行改进:
class TableViewController: UITableViewController
var biggestTopSafeAreaInset: CGFloat = 0
override func viewSafeAreaInsetsDidChange()
super.viewSafeAreaInsetsDidChange()
self.biggestTopSafeAreaInset = max(view.safeAreaInsets.top, biggestTopSafeAreaInset)
func scrollToTop(animated: Bool)
if traitCollection.verticalSizeClass == .compact
tableView.setContentOffset(CGPoint(x: 0, y: -view.safeAreaInsets.top), animated: animated)
else
tableView.setContentOffset(CGPoint(x: 0, y: -biggestTopSafeAreaInset), animated: animated)
还有一种情况会导致大标题滚动后不显示。
如果用户:
-
在横向模式下旋转设备打开应用。
滚动视图。
纵向旋转设备。
此时 maximumTopSafeAreaInset 还没有机会找到最大值,如果调用 scrollToTop 方法,大标题将不会显示。 幸运的是,这种情况不应该经常发生。
【讨论】:
以上是关于UIScrollView + LargeTitle (iOS 11) - 滚动到顶部并显示大标题的主要内容,如果未能解决你的问题,请参考以下文章
如何在当前 vc 上获得 largeTitle,但在 vc 上获得小标题?
带有 UISegmentedControl 和 childViewController 的 iOS LargeTitle(在容器中)