6 votes

swiftui - Comment éviter l'erreur "Unable to simultaneously satisfy constraints" ?

J'essaie d'appliquer le code de la réponse acceptée à cette sur la façon de faire en sorte qu'un champ de texte SwiftUI devienne un premier intervenant. Voici le code, copié de cette réponse, que j'ai essayé d'utiliser dans 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
        }
    }
}

L'exécution de ce code, cependant, me donne une erreur d'exécution, disant "Unable to simultaneously satisfy constraints" (Impossible de satisfaire simultanément les contraintes). L'erreur est illustrée ci-dessous.

dans makeUIView

dans updateUIView dans onEditingChanged 2020-08-14 16:02:48.445045-0600 OpenRussian [2965:122005] [LayoutConstraints] Impossible de satisfaire simultanément les contraintes. simultanément les contraintes. Il est probable qu'au moins une des contraintes de la liste suivante est une contrainte que vous ne voulez pas. Essayez ceci : (1) regardez chaque et essayez de trouver celle que vous n'attendez pas ; (2) trouvez le code qui a ajouté la ou les contraintes non désirées et corrigez-le. ( "<NSLayoutConstraint:0x600002580d20 'assistantHeight' TUISystemInputAssistantView:0x7fde585064a0.height == 44 (active)>", "<NSLayoutConstraint:0x600002591b30 'assistantView.bottom' TUISystemInputAssistantView:0x7fde585064a0.bottom == _UIKBCompatInputView:0x7fde51b78c50.top (active)>", "<NSLayoutConstraint:0x600002591ae0 'assistantView.top' V:|-(0)-[TUISystemInputAssistantView:0x7fde585064a0] (active, names : '|':UIInputSetHostView:0x7fde58518070 )>", "<NSLayoutConstraint:0x600002591720 'inputView.top' V:|-(0)-[_UIKBCompatInputView:0x7fde51b78c50] (active, names : '|':UIInputSetHostView:0x7fde58518070 )>" )

Tentera de se rétablir en brisant la contrainte <NSLayoutConstraint:0x600002591b30 'assistantView.bottom' TUISystemInputAssistantView:0x7fde585064a0.bottom == _UIKBCompatInputView:0x7fde51b78c50.top (active)>

Créer un point d'arrêt symbolique à UIViewAlertForUnsatisfiableConstraints afin d'identifier ce problème dans le débogueur. Les méthodes de la classe UIConstraintBasedLayoutDebugging sur UIView listées dans <UIKitCore/UIView.h> peuvent également être utiles.

Que puis-je modifier pour que cela fonctionne et pour éviter cette erreur d'exécution "unable to simultaneously satisfy constraints" ?

1voto

Asperi Points 123157

Essayez une variante légèrement corrigée fournie ci-dessous (avec vue de test). Testé avec Xcode 12 / iOS 14 - aucun avertissement de la console n'a été observé.

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)
        }
    }
}

1voto

Eldar Points 124

Examinons-les un par un :

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

Cela signifie que la vue 0x7fde585064a0 est active et qu'elle a une hauteur de 44 points.

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

Cela signifie que le bord supérieur de 0x7fde585064a0 doit être à 0 point du haut de sa vue secondaire 0x7fde58518070.

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

Cela signifie que les vues 0x7fde51b78c50 et 0x7fde585064a0 sont en conflit. Ces quatre choses ne peuvent pas toutes être vraies. Et le problème avec les contraintes 0x600002591b30. Déterminez où se situe le problème et définissez une contrainte réelle.

Je pense qu'il est utile de connaître les bases et de comprendre ce qu'Apple / Xcode essaie de vous dire via les logs :

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]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X