UIScrollView 是否自动调整 contentOffset 以适应安全区域?

Does the UIScrollView automatically adjust contentOffset to fit inside the safe area?

我添加了一个 UIScrollView 和 3 个 UIView。

我已经三次检查了 UIScrollView 的框架、UIViews 的框架、contentOffset、superview 的框架,通常所有相关内容。

出于某种原因,这是我将 contentOffset 设置为 (0,0) 时出现的内容:

我的项目中没有从该偏移原点开始的视图。

scrollView 假定 (0, 0) 为 (0, 50) 左右的值,这是导航栏的高度,即使我没有使用它也是如此。

编辑

奇怪的是,如果我在设备处于横向模式时打开应用程序,contentOffset 行为正常。因此,由于设备的下巴,它必须进行一些自动调整。

编辑 2

我在没有下巴的设备(iPhone 8)上打开应用程序,然后 contentOffset 自动调整到状态栏的高度。意思是 (0, 0) 不是 (0, 0) 而是 (0, heightOfStatusBar).

编辑 3

在 iPad 上它表现正常,即使 iPad 确实有状态栏!

如何在每种情况下将其固定为 (0,0)?

UIScrollView 有一个 属性 在其中“插入”内容,这样安全区域就不会重叠。

可以通过设置 UIScrollView 实例的 contentInsetAdjustmentBehavior 属性 来更改,如下所示:

scrollView.contentInsetAdjustmentBehavior = .never

请注意,调整的不是 contentOffset,而是 contentInset。这就是为什么在所有情况下内容偏移量仍然是 (0, 0) 的原因。

此外,如果您正在构建低于 iOS 11.0 的 iOS 开发目标,您可能会遇到构建错误。在这种情况下,您可以改用以下代码。

if #available(iOS 11.0, *){
    scrollView.contentInsetAdjustmentBehavior = .never
}

参考资料

Apple Developer Docs - contentinsetadjustmentbehavior

不,contentOffset 不会影响安全区域,反之亦然。 contentOffset 用于 scrollView 内部滚动的编程。

如果您想 link UIScrollView 到框架的边界,您必须使用自动布局并激活一些约束。一步一步:

  1. set 属性 translatesAutoresizingMaskIntoConstraints of scroll view 为 false scrollView.translatesAutoresizingMaskIntoConstraints = 假
  2. 初始化约束
  3. 激活约束(在 viewDidLoad 中)

scrollView.translatesAutoresizingMaskIntoConstraints = 假

    let constraints: [NSLayoutConstraint] = [
        scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        scrollView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        scrollView.widthAnchor.constraint(equalTo: view.widthAnchor),
        scrollView.heightAnchor.constraint(equalTo: view.heightAnchor)
    ]
    NSLayoutConstraint.activate(constraints)

因此,您的滚动视图将 link 编辑到 phone 边界的边缘。并且 contentOffset 将等于 (0, 0)。相反,如果你想 link 将 scrollView 滚动到安全区域,你必须使用 view.layoutMarginsGuide,在那里你可以找到各种锚点。

每个 UIView 对象都与父视图协调系统一起工作。你的 scrollView 对状态栏、导航栏和工具栏一无所知。例如,任何 UIView 的框架原点是 (0,0).

所以,总结一下:

  1. 到link你将视图滚动到安全区域你需要设置约束。
  2. contentOffset 用于在 scrollView 中编程滚动。