【问题标题】:swiftui - how to avoid 'Unable to simultaneously satisfy constraints' error?swiftui - 如何避免“无法同时满足约束”错误?
【发布时间】:2020-12-04 19:09:59
【问题描述】:

我正在尝试将代码应用到this 问题的已接受答案中,以了解如何使 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
        }
    }
}

但是,运行该代码会给我一个运行时错误,提示“无法同时满足约束条件”。错误如下所示。

在makeUIView中

在 onEditingChanged 中的 updateUIView 2020-08-14 16:02:48.445045-0600 OpenRussian[2965:122005] [LayoutConstraints] 无法同时 满足约束。可能至少有一个约束条件 以下列表是您不想要的。试试这个:(1)看每个 约束并尝试找出您不期望的; (2) 找到 添加不需要的约束或约束的代码并修复它。 ( "<0x600002580d20 tuisysteminputassistantview:0x7fde585064a0.height="="><0x600002591b30 tuisysteminputassistantview:0x7fde585064a0.bottom="=" _uikbcompatinputview:0x7fde51b78c50.top><0x600002591ae0 v:><0x600002591720 v:>

<0x600002591b30 tuisysteminputassistantview:0x7fde585064a0.bottom="=" _uikbcompatinputview:0x7fde51b78c50.top>

    标签: swift xcode swiftui uikit


    【解决方案1】:

    让我们一一来看看:

    &lt;NSLayoutConstraint:0x600002580d20 'assistantHeight' TUISystemInputAssistantView:0x7fde585064a0.height == 44 (active)&gt;

    这表示视图 0x7fde585064a0 处于活动状态,高度为 44 点

    &lt;NSLayoutConstraint:0x600002591ae0 'assistantView.top' V:|-(0)-[TUISystemInputAssistantView:0x7fde585064a0] (active, names: '|':UIInputSetHostView:0x7fde58518070 )&gt;

    这就是说 0x7fde585064a0 的上边缘必须与其父视图 0x7fde58518070 的顶部有 0 个点的差距

    &lt;NSLayoutConstraint:0x600002591b30 'assistantView.bottom' TUISystemInputAssistantView:0x7fde585064a0.bottom == _UIKBCompatInputView:0x7fde51b78c50.top (active)&gt;

    这是说视图 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]
    

    【讨论】:

      【解决方案2】:

      尝试下面提供的稍微更正的变体(带有测试视图)。使用 Xcode 12 / iOS 14 测试 - 未观察到控制台警告。

      struct CustomTextField: UIViewRepresentable {
      
          class Coordinator: NSObject, UITextFieldDelegate {
      
              @Binding var text: String
              var didBecomeFirstResponder = false
      
              init(text: Binding<String>) {
                  _text = text
              }
      
              func textFieldDidChangeSelection(_ textField: UITextField) {
                  DispatchQueue.main.async {
                      self.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
              textField.setContentHuggingPriority(.defaultHigh, for: .vertical)
              textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
      
              DispatchQueue.main.async {
                  textField.becomeFirstResponder()
              }
              return textField
          }
      
          func makeCoordinator() -> CustomTextField.Coordinator {
              return Coordinator(text: $text)
          }
      
          func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<CustomTextField>) {
              uiView.text = text
          }
      }
      
      struct TestConstraintsError: View {
          @State private var text = ""
          var body: some View {
              VStack {
                  Text("Input: " + text)
                  CustomTextField(text: $text, isFirstResponder: true)
                      .padding()
                      .border(Color.red)
              }
          }
      }
      

      【讨论】:

      • 原来有时我会收到控制台警告,有时却没有,我不确定是什么导致了这种差异。我在另一个类似的问题中读到这是一个苹果问题。警告现在已经消失,如果它们回来,我将计划尝试您的解决方案。感谢您的回复!
      • 控制台警告回来了,我尝试了这个解决方案——但是,我得到了相同的控制台消息。
      猜你喜欢
      • 2023-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-28
      • 1970-01-01
      • 2014-10-27
      • 2014-06-19
      • 1970-01-01
      相关资源
      最近更新 更多