swiftui - 如何避免“无法同时满足约束”错误?

mhe*_*rzl 6 xcode uikit swift swiftui

我正在尝试将此问题的已接受答案中的代码应用于如何使 SwiftUI TextField 成为第一响应者。这是从该答案复制的代码,我尝试在 xcode 中使用它:

struct CustomTextField: UIViewRepresentable {

    class Coordinator: NSObject, UITextFieldDelegate {

        @Binding var text: String
        var didBecomeFirstResponder = false

        init(text: Binding<String>) {
            _text = text
        }

        func textFieldDidChangeSelection(_ textField: UITextField) {
            text = textField.text ?? ""
        }

    }

    @Binding var text: String
    var isFirstResponder: Bool = false

    func makeUIView(context: UIViewRepresentableContext<CustomTextField>) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.delegate = context.coordinator
        return textField
    }

    func makeCoordinator() -> CustomTextField.Coordinator {
        return Coordinator(text: $text)
    }

    func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<CustomTextField>) {
        uiView.text = text
        if isFirstResponder && !context.coordinator.didBecomeFirstResponder  {
            uiView.becomeFirstResponder()
            context.coordinator.didBecomeFirstResponder = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,运行该代码会给我一个运行时错误,说“无法同时满足约束”。错误如下所示。

在 makeUIView

在 onEditingChanged 2020-08-14 16:02:48.445045-0600 OpenRussian[2965:122005] [LayoutConstraints] 中的 updateUIView 中无法同时满足约束。可能以下列表中的至少一项约束是您不想要的。试试这个: (1) 查看每个约束并尝试找出您不期望的;(2) 找到添加不需要的约束或约束的代码并修复它。( “<NSLayoutConstraint:0x600002580d20 'assistantHeight' TUISystemInputAssistantView:0x7fde585064a0.height == 44(活性)>”, “<NSLayoutConstraint:0x600002591b30 'assistantView.bottom' TUISystemInputAssistantView:0x7fde585064a0.bottom == _UIKBCompatInputView:0x7fde51b78c50.top(活性)>” , "<NSLayoutConstraint:0x600002591ae0 'assistantView.top' V:

将尝试通过打破约束来恢复 <NSLayoutConstraint:0x600002591b30 'assistantView.bottom' TUISystemInputAssistantView:0x7fde585064a0.bottom == _UIKBCompatInputView:0x7fde51b78c50.top (active)>

在 UIViewAlertForUnsatisfiableConstraints 处创建一个符号断点以在调试器中捕获它。<UIKitCore/UIView.h> 中列出的 UIView 上的 UIConstraintBasedLayoutDebugging 类别中的方法也可能有帮助。

我可以修改什么来完成这项工作,并避免这种“无法同时满足约束”的运行时错误?

Eld*_*dar 1

让我们一一看看:

<NSLayoutConstraint:0x600002580d20 'assistantHeight' TUISystemInputAssistantView:0x7fde585064a0.height == 44 (active)>

这表示视图 0x7fde585064a0 处于活动状态并且具有 44 点高度

<NSLayoutConstraint:0x600002591ae0 'assistantView.top' V:|-(0)-[TUISystemInputAssistantView:0x7fde585064a0] (active, names: '|':UIInputSetHostView:0x7fde58518070 )>

这就是说,0x7fde585064a0 的顶部边缘与其超级视图 0x7fde58518070 的顶部必须有 0 点的间隙

<NSLayoutConstraint:0x600002591b30 'assistantView.bottom' TUISystemInputAssistantView:0x7fde585064a0.bottom == _UIKBCompatInputView:0x7fde51b78c50.top (active)>

这表示视图 0x7fde51b78c50 和 0x7fde585064a0 存在冲突。这四件事不可能都是真的。以及约束 0x600002591b30 的问题。找出问题所在并设置真正的约束。

我认为了解基础知识并了解 Apple / Xcode 试图通过日志告诉您什么是有用的:

H = Horizontal constraint(for leading and Trailing)
V = Vertical constraint(top and bottom edge)
h = height
w = width

TopEdge    -> V:|-(points)-[VIEW:memoryAddress] 
BottomEdge -> V:[VIEW:memoryAddress]-(points)-|
Leading    -> H:|-(points)-[VIEW:memoryAddress] 
Trailing   -> H:[VIEW:memoryAddress] -(points)-|
height     -> h= --& v=--& V:[VIEW:memoryAddress((points)] 
width      -> VIEW:memoryAddress.width == points 
between    -> H:[VIEW 1]-(51)-[VIEW 2]
Run Code Online (Sandbox Code Playgroud)