SwiftUI上下文菜单是否使用LayoutConstraints?

时间:2019-12-09 17:57:20

标签: swiftui

我假设SwiftUI不再使用NSLayoutContstraints。但是,我在控制台中遇到约束错误。任何人都知道如何调试吗?

打开上下文菜单时,如果使用列表视图,则会显示以下内容:

  

2019-12-09 10:52:52.029091-0700 ContextMenuTest [26384:13138419] [LayoutConstraints]无法同时满足约束。       以下列表中至少有一个约束是您不想要的约束。       尝试这个:           (1)查看每个约束,并尝试找出不期望的约束;           (2)查找添加了一个或多个不必要约束的代码并进行修复。       (注意:如果看到的是您不了解的NSAutoresizingMaskLayoutConstraints,请参阅有关UIView属性translationsAutoresizingMaskIntoConstraints的文档)   (       “”,       “ = 44(活动,名称:groupView.actionsSequence ...:0x7fd98781de00)>”,       “”,       “”,       “”,       ”   )

     

将尝试通过打破约束来恢复   = 44(活动,名称:groupView.actionsSequence ...:0x7fd98781de00)>

     

在UIViewAlertForUnsatisfiableConstraints上创建一个符号断点,以在调试器中捕获该断点。   列出的UIView的UIConstraintBasedLayoutDebugging类别中的方法也可能有用。

struct ContentView: View {
    var body: some View {
        List {
            Text("one")
            Text("two")
                .contextMenu(menuItems: {
                    Text("test")
                })
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我当时假设SwiftUI不再使用 NSLayoutContstraints。

这只是正确。如果您检查视图层次结构,则SwiftUI仍将使用UIKit组件,并且大多数组件没有公开的约束。但是某些“桥接”视图在底层具有NSLayoutConstraints作为其基础UIView类。

警报,弹出窗口和上下文菜单等某些组件也可以看到您的问题,因为它们很复杂,因此尚未完全移植。

UIViewAlertForUnsatisfiableConstraints使用符号断点:

po UIApplication.shared.windows.first?.constraints

({UIWindowUIViewhttps://developer.apple.com/documentation/uikit/uiwindow的子类。

根托管控制器及其子视图没有任何约束,因为它们已完全移植到SwiftUI新的环境变量语法中。

po UIApplication.shared.windows.first?.rootViewController?.view.constraints

SwiftUI的许多运行时库仍具有NSLayoutConstraints。请参阅:context menualert view等。

请注意,您需要切换到主堆栈框架才能访问UIApplication.sharedAppDelegate)。见下文:

Debug Navigator snippet

如何检查视图层次结构?

使用dump,您可以查看SwiftUI信息(不仅仅是po):

po dump(UIApplication.shared.windows.first?.rootViewController)

列出了控制器的UIKit桥接类,例如

contextMenuBridge: Optional(<_TtGC7SwiftUI17ContextMenuBridgeV33Demo11ContentView_: 0x600002c8c720>)
      ▿ some: <_TtGC7SwiftUI17ContextMenuBridgeV33Demo11ContentView_: 0x600002c8c720> #81
        - super: NSObject
        ▿ host: Optional(<_TtGC7SwiftUI14_UIHostingViewV33Demo11ContentView_: 0x7fccd7403690; frame = (0 0; 414 896); autoresize = W+H; gestureRecognizers = <NSArray: 0x6000006f0d20>; layer = <CALayer: 0x6000008b5180>>)
          ▿ some: <_TtGC7SwiftUI14_UIHostingViewV33Demo11ContentView_: 0x7fccd7403690; frame = (0 0; 414 896); autoresize = W+H; gestureRecognizers = <NSArray: 0x6000006f0d20>; layer = <CALayer: 0x6000008b5180>> #0
        ▿ presentedMenuID: SwiftUI.ViewIdentity
          - seed: 0
        - interaction: nil
        - cachedPreferences: 0 elements
        ▿ seed: empty
          - value: 0
        - currentPreference: nil
        - cachedPlatformActions: 0 elements
        - cachedPreview: nil
    - accessibilityEnabled: false
    - cachedAccessibilityNodes: 0 elements
    - accessibilityNeedsUpdate: true
    - scrollTest: nil
    - delegate: nil
    - parentAccessibilityElement: nil

可以为警报,工作表和其他“桥接”类找到类似的窗口约束。

使用以下方法修复错误:

UIApplication.shared.windows[0].translatesAutoresizingMaskIntoConstraints = false

但是请注意,一旦SwiftUI成熟并退出测试版,这些桥梁就可能被删除。