SwiftUI 上下文菜单是不是使用 LayoutConstraints?
Posted
技术标签:
【中文标题】SwiftUI 上下文菜单是不是使用 LayoutConstraints?【英文标题】:Do SwiftUI Context Menus use LayoutConstraints?SwiftUI 上下文菜单是否使用 LayoutConstraints? 【发布时间】:2019-12-09 17:57:20 【问题描述】:我假设 SwiftUI 不再使用 NSLayoutConstraints。但是我在控制台中遇到约束错误。有人知道如何调试吗?
当我打开上下文菜单时,如果使用列表视图会打印出以下内容:
2019-12-09 10:52:52.029091-0700 ContextMenuTest[26384:13138419] [LayoutConstraints] 无法同时满足约束。 以下列表中的至少一个约束可能是您不想要的。 试试这个: (1)查看每个约束并尝试找出您不期望的; (2) 找到添加了一个或多个不需要的约束的代码并修复它。 (注意:如果您看到不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档) ( "", “= 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】:我假设 SwiftUI 不再使用 NSLayoutConstraints。
这只是不是正确的。如果您检查视图层次结构,SwiftUI
仍然使用 UIKit
组件,并且大多数组件没有暴露的约束。但是一些“桥接”视图在其底层 UIView
类中有 NSLayoutConstraints
。
警报、弹出框和上下文菜单等某些组件也会看到您的问题,因为这些组件很复杂,因此尚未完全移植。
对UIViewAlertForUnsatisfiableConstraints
使用符号断点:
po UIApplication.shared.windows.first?.constraints
(UIWindow
是UIView
的子类)https://developer.apple.com/documentation/uikit/uiwindow。
根宿主控制器及其子视图没有任何限制,因为它们已完全移植到 SwiftUI 新的环境变量语法。
po UIApplication.shared.windows.first?.rootViewController?.view.constraints
SwiftUI 的许多运行时库仍然有NSLayoutConstraints
。请参阅:context menu、alert view 等。
请注意,您需要切换到主堆栈框架才能访问UIApplication.shared
(AppDelegate
)。见下文:
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 成熟并退出测试版,这些桥梁可能会被移除。
【讨论】:
修复对我来说没有帮助......在不同的地方尝试过(比如 SceneDelegate 或直接在 SwiftUI 文件中)以上是关于SwiftUI 上下文菜单是不是使用 LayoutConstraints?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI嵌入在Form或Section中的视图上下文菜单(contextMenu)无法独立弹出的解决