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

wsh*_*amp 8 swiftui

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

当我打开上下文菜单时,如果使用列表视图,则会打印出以下内容:

2019-12-09 10:52:52.029091-0700 ContextMenuTest[26384:13138419] [LayoutConstraints] 无法同时满足约束。可能以下列表中的至少一项约束是您不想要的。试试这个: (1) 查看每个约束并尝试找出您不期望的;(2) 找到添加不需要的约束或约束的代码并修复它。(注意:如果看到 NSAutoresizingMaskLayoutConstraints 不明白,请参考 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档) ( "", "= 44 (active, names: 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")
                })
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Pra*_*tti 2

\n

我假设 SwiftUI 不再使用 NSLayoutContstraints。

\n
\n\n

这是正确的。SwiftUI如果您检查视图层次结构,仍然使用UIKit组件,并且大多数组件没有公开的约束。但一些“桥接”观点在幕后是NSLayoutConstraints针对其基类的。UIView

\n\n

某些组件(如警报、弹出窗口和上下文菜单)也会出现您的问题,因为这些组件很复杂,因此尚未完全移植。

\n\n

使用符号断点UIViewAlertForUnsatisfiableConstraints

\n\n
po UIApplication.shared.windows.first?.constraints\n
Run Code Online (Sandbox Code Playgroud)\n\n

(是https://developer.apple.com/documentation/uikit/uiwindowUIWindow的子类UIView)。

\n\n

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

\n\n
po UIApplication.shared.windows.first?.rootViewController?.view.constraints\n
Run Code Online (Sandbox Code Playgroud)\n\n

SwiftUI 的许多运行时库仍然具有NSLayoutConstraints. 请参阅:上下文菜单警报视图等。

\n\n

请注意,您需要切换到主堆栈帧才能访问UIApplication.shared( AppDelegate)。见下文:

\n\n

调试导航器片段

\n\n

如何检查视图层次结构?

\n\n

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

\n\n
po dump(UIApplication.shared.windows.first?.rootViewController)\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

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

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

\n\n

使用以下方法修复错误:

\n\n
UIApplication.shared.windows[0].translatesAutoresizingMaskIntoConstraints = false\n
Run Code Online (Sandbox Code Playgroud)\n\n

但请注意,一旦 SwiftUI 成熟并结束测试版,这些桥梁可能会被删除。

\n