5

我使用以下代码滚动到 UICollectionView 的顶部:

scrollView.scrollRectToVisible(CGRect(origin: .zero, size: CGSize(width: 1, height: 1)), animated: true)

UINavigationBar但是,在 iOS 11 和 12 上,scrollView 仅滚动到顶部,而不会显示(when prefersLargeTitlehas been set to true)的大标题。

这是它的样子: 在此处输入图像描述

我想要达到的结果:

在此处输入图像描述

4

3 回答 3

6

它按设计工作,您正在滚动到 position y = 0,将您指定controllerUIScrollView委托并打印出滚动偏移量:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    print(scrollView.contentOffset)
}

您将看到何时显示大标题并且您移动滚动视图 a 但是它会跳回大标题它不会打印(0.0, 0.0)但是(0.0, -64.0)(0.0, -116.0)- 这是相同的值scrollView.adjustedContentInset,所以如果您想向上滚动并显示大标题,您应该做:

scrollView.scrollRectToVisible(CGRect(x: 0, y: -64, width: 1, height: 1), animated: true)
于 2018-08-17T10:35:37.037 回答
5

您不想使用任何“魔法值”(在当前接受的答案中为 -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)
    }
}
于 2021-02-24T11:25:20.733 回答
1

似乎使用负内容偏移是要走的路。

我真的很喜欢 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)
        }
    }
}

还有一种情况可能会导致滚动后大标题不显示。

如果用户:

  1. 以横向模式旋转设备打开应用程序。
  2. 滚动视图。
  3. 纵向旋转设备。

此时 maximumTopSafeAreaInset 还没有机会找到最大值,如果调用 scrollToTop 方法,大标题将不会显示。幸运的是,这种情况不应该经常发生。

于 2021-03-30T11:29:24.413 回答