iPhone X上安全区域在子视图不在视图区域时无法正常工作

15

我有一个scrollView包含2个子viewController。您会发现VC2的布局不正确。

我发现,如果视图尚未在屏幕上可见,则safeAreaInsets始终为0。

当滚动结束时,我可以调用vc2.view.setNeedsLayout()来解决此问题。但是直到滚动结束后布局才被修正。

文档说:

如果视图当前未安装在视图层次结构中或尚未显示在屏幕上,则此属性中的边缘插图为0。

那么我该如何解决这种情况呢?

enter image description here

自动布局 enter image description here enter image description here


你需要提供更多信息,展示一下“VC1底部”和“VC2底部”的限制条件是什么样子的。它们完全相同吗? - jonaszmclaren
是的。它们都是相同的限制条件,一个是居中到安全区域,另一个是底部到安全区域。 - PowHu
你是否尝试在viewDidLayoutSubviews()或类似的地方放置vc2.view.setNeedsLayout()?(附带适当的测试以防止潜在的无限循环) - Zaphod
viewDidLayoutSubviews()是相同的。当视图不在屏幕上时,安全区域始终为0。 - PowHu
2
有没有找到任何解决方案?我也遇到了同样的问题,而且我正在针对iOS10进行开发,无法使用safeAreaInsets - Giovanni Trezzi
在其他设备上是否出现了相同的问题(例如 iPhone 8、iPhone 8 Plus)?因为您正在处理 UIScrollView,这意味着需要使用一些技巧来布置滚动视图中的子视图。本文档提供了一些技术概述:https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html - Yevhen Dubinin
4个回答

12

不要引用当前视图的safeAreaInsets,而是将其设置为UIApplication:

(UIApplication.shared.delegate?.window??.safeAreaInsets.bottom)

safeAreaInsets 仅在目标 iOS 11.0 或更高版本上可用。 - Giovanni Trezzi
没问题,就我所知,旧设备本来就没有安全区域插图。 - jalone

3
在您的子视图控制器中,如果将视图控制器的 additionalSafeAreaInsets 设置为窗口的安全区域插图,则它们将正确布局并尊重安全区域。
我发现我必须在 viewDidLoad() viewWillTransition(to size:CGSize,with coordinator:UIVIewControllerTransitionCoordinator 内执行此操作。
viewWillTransition 内,您将希望在协调器的动画块中设置 additionalSafeAreaInsets
coordinator.animate(alongsideTransition: { _ in
    if #available(iOS 11.0, *) {
        self.additionalSafeAreaInsets = UIApplication.shared.delegate?.window??.safeAreaInsets
    }
}, completion: nil)

2
我正在构建一个自定义分页视图控制器,也遇到了@PowHU同样的问题。
唯一似乎起作用的解决方案是在故事板中将视图控制器的视图类设置为我创建的自定义类AlwaysSafeAreaInsetsView
import UIKit

class AlwaysSafeAreaInsetsView: UIView {

    @available(iOS 11.0, *)
    override var safeAreaInsets: UIEdgeInsets {
        if let window = UIApplication.shared.keyWindow {
            return window.safeAreaInsets
        }
        return super.safeAreaInsets
    }

}

0
如果我看得正确,您的容器视图被固定在其父视图的顶部和底部。将其固定到安全区域,您的子视图控制器将被正确布局。

3
不行。我希望容器视图的大小与父视图相同。 - PowHu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接