Importing SwiftUI safeAreaInset into UIKit

lhu*_*ath 5 uikit safearealayoutguide swiftui

safeAreaInset(edge:alignment:spacing:content:):

\n
\n

The modified view is inset by the height of content, from edge, with its safe area increased by the same amount.

\n
\n

看来 SwiftUIsafeAreaInset没有导入 UIKit 的安全区域:

\n
        ZStack {\n            Color.black\n            UIKitView()\n        }\n        .ignoresSafeArea(edges: .top)\n        .safeAreaInset(edge: .top) {\n            Text("TOP")\n                .frame(minHeight: 200)\n                .background(Color.cyan.opacity(0.5))\n        }\n
Run Code Online (Sandbox Code Playgroud)\n

在此示例中,视图black和 的UIKitView布局相同 - 它们忽略safeAreaInset:top和状态栏。

\n

问题是:如何了解UIKitView游戏中的安全区域?

\n

考虑以下:

\n
struct UIKitView: UIViewControllerRepresentable {\n    func makeUIViewController(context: Context) -> some UIViewController { ViewController() }\n    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}\n    \n    class ViewController: UIViewController {\n        let bgView = UILabel()\n        let safeView = UILabel()\n\n        override func viewDidLoad() {\n            bgView.backgroundColor = .red.withAlphaComponent(0.5)\n            self.view.addSubview(bgView)\n            safeView.backgroundColor = .green.withAlphaComponent(0.5)\n            self.view.addSubview(safeView)\n        }\n\n        override func viewWillLayoutSubviews() {\n            self.bgView.frame = self.view.bounds\n            self.safeView.frame = self.view.safeAreaLayoutGuide.layoutFrame\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我们现在看到由 生成的两层UIKitView,一层代表视图的完整框架 ( red),另一层仅限于已知的安全区域 ( green)。

\n

现在很清楚的是,UIKit 的安全区域受到状态栏的限制,但不受safeAreaInset:top. 这是令人惊讶的 \xe2\x80\x93 我们如何才能了解游戏中的完整顶部安全区域并正确调整绿色视图以适应手动放置在其上方的内容?

\n

由此产生的布局

\n

Moj*_*ini 1

看来你混淆了一些概念。

\n
    \n
  1. ZStack仅将视图堆叠在一起,与safeArea.

    \n
  2. \n
  3. 您正在使用一些静态代码在预构建UIViewController函数内执行环境布局操作,例如直接分配框架。因此它不会根据需要更新 UI。

    \n
  4. \n
\n

一个更好的例子可以解释它本身:

\n

请尝试以下操作来查看您正在寻找的内容:

\n
struct ContentView: View {\n    var body: some View {\n        NavigationView {\n            ZStack {\n                Color.black\n                UIKitView()\n            }\n            .ignoresSafeArea(edges: .top)\n            .navigationTitle("Hello World")\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

演示图片

\n

通过添加NavigationView尊重安全区域的内容,您可以看到:

\n
    \n
  1. 超出SwiftUI.Color.Black以下但低于以下top​​SafeAreaNavigationBarbottomSafeArea

    \n
  2. \n
  3. safeView绿色的)完全位于safeArea您手动设置的位置safeAreaLayoutGuide.layoutFrame,这是视图中未被条形图和其他内容遮挡的部分

    \n
  4. \n
  5. (红色的)的大小bgView和位置与 完全相同SwiftUI.Color.Black。因为它是由SwiftUI布局系统处理的。

    \n
  6. \n
\n

所以

\n
    \n
  • 如果你想让控件来SwiftUI布局,就用框架。
  • \n
  • 如果您想忽略SwiftUI布局并访问安全区域environment(可以是状态栏或任何其他栏(如导航栏,甚至物理对象,如缺口或动态岛)),请使用内部查看的safeAreaLayoutGuide.
  • \n
\n

希望它能解释其中的区别。

\n

  • @aehlke 不幸的是没有 (2认同)