斯威夫特 - 如何避免'Unable to simultaneously satisfy constraints'错误?



我正在尝试将已接受的答案中的代码应用于这个问题,关于如何使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 中

在updateUI中查看onEditingChanged 2020-08-14 16:02:48.44455045-0600OpenRussian〔2965:122005〕〔LayoutConstraints〕无法同时满足约束。可能至少有一个下面的清单是你们不想要的。试试这个:(1(看看每一个约束自己,试着弄清楚哪些是你没有预料到的;(2( 查找添加了不需要的约束并进行修复的代码。("lt;NSLayoutConstraint:0x600002580d20"assistantHeight"TUISystemInputAssistantView:0x7fde850064a0.height==44(活动(>";,"lt;NSLayoutConstraint:0x600002591b30"assistantView.bottom"TUISystemInputAssistantView:0x7fde850064a0.bottom==_UIKBCompatInputView:0x7fde51b78c50.top(活动(>";,"lt;NSLayoutConstraint:0x600002591ae0"assistantView.top"V:|-(0(-[TUISystemInputAssistantView:0x7fde850064a0](活动,名称:"|":UIInputSetHostView:0x7fde8518070(>";,"lt;NSLayoutConstraint:0x600002591720"inputView.top"V:|-(0(-[UIKBCompatInputView:0x7fde51b78c50](活动,名称:"|":UIInputSetHostView:0x7fde8518070(>quot;(

将尝试通过打破约束来恢复<NSLayoutConstraint:0x600002591b30"assistantView.bottom"TUI系统输入助理视图:0x7fde850064a0.bottom==_UIKBCompatInputView:0x7fde51b78c50.top(活动(>

在UIViewAlertForUnsatisfableConstraints处设置符号断点以在调试器中捕获此。中的方法中列出的UIView上的UIConstraintBasedLayoutDebugging类别<UIKitCore/UIView.h>可能也会有所帮助。

我可以修改什么来实现这一点,并避免这种"无法同时满足约束"的运行时错误?

让我们逐一来看一下:

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

这意味着视图0x7fde850064a0处于活动状态,具有44点高度

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

这意味着0x7fde585064a0的顶部边缘必须与其超级视图0x7fde 8518070 的顶部相距0点

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

这意味着视图0x7fde51b78c50和0x7fde 85064a0冲突。这四件事不可能都是真的。以及约束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]

尝试下面提供的经过一点更正的变体(带有测试视图(。使用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)
}
}
}

相关内容

最新更新