Incapace di soddisfare simultaneamente i vincoli, tenterà di recuperare rompendo il vincolo


145

Di seguito è riportato il messaggio di errore che ricevo nell'area di debug. Funziona bene e nulla è sbagliato tranne che ricevo questo errore. Ciò impedirebbe ad Apple di accettare l'app? Come lo aggiusto?

2012-07-26 01:58:18.621 Rolo[33597:11303] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x887d630 h=--& v=--& V:[UIButtonLabel:0x886ed80(19)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x887d5f0 h=--& v=--& UIButtonLabel:0x886ed80.midY == + 37.5>",
    "<NSAutoresizingMaskLayoutConstraint:0x887b4b0 h=--& v=--& V:[UIButtonLabel:0x72bb9b0(19)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x887b470 h=--& v=--& UIButtonLabel:0x72bb9b0.midY == - 0.5>",
    "<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]>",
    "<NSLayoutConstraint:0x72c2430 UILabel:0x72bfad0.top == UILabel:0x72bf7c0.top>",
    "<NSLayoutConstraint:0x72c2370 UILabel:0x72c0270.top == UILabel:0x72bfad0.top>",
    "<NSLayoutConstraint:0x72c22b0 V:[UILabel:0x72bf7c0]-(NSSpace(8))-[UIButton:0x886efe0]>",
    "<NSLayoutConstraint:0x72c15b0 V:[UILabel:0x72c0270]-(NSSpace(8))-[UIRoundedRectButton:0x72bbc10]>",
    "<NSLayoutConstraint:0x72c1570 UIRoundedRectButton:0x72bbc10.baseline == UIRoundedRectButton:0x7571170.baseline>",
    "<NSLayoutConstraint:0x72c21f0 UIRoundedRectButton:0x7571170.top == UIButton:0x886efe0.top>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]>

Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

1
Questo errore si verificherà solo in Xcode 4.5, quindi non è possibile
inviarlo

Quindi non c'è niente di sbagliato allora? E sarebbe possibile utilizzare un'altra versione di xcode per poter inviare all'app store?
Johnny Cox,

1
Sì, c'è qualcosa che non va, ma è irrilevante perché ha a che fare con una funzionalità di iOS che non è ancora disponibile nelle versioni Xcode pubbliche. Se viene compilato con 4.4, è possibile rilasciarlo utilizzando quella versione (è stato rilasciato oggi).
Borrrden,

Ricevo questo messaggio di errore per le app OS X in Xcode 4.4. Non lo capisco
Steve McLeod,

@ Bartłomiej Semańczyk Potresti per caso unirti alla stanza: chat.stackoverflow.com/rooms/92522/autolayout-and-ios ? Mi dispiace che sia casuale, ma apprezzerei i tuoi consigli su qualcosa relativo al layout automatico, grazie!
Cheznead,

Risposte:


275

Consiglierei di eseguire il debug e trovare quale vincolo è "quello che non vuoi" . Supponiamo di avere il seguente problema:

inserisci qui la descrizione dell'immagine

Il problema è sempre come trovare i seguenti vincoli e viste.

Esistono due soluzioni per eseguire questa operazione:

  1. DEBUG VIEW HERARCHY (Non raccomandare in questo modo)

Dato che sai dove trovare vincoli imprevisti (PBOUserWorkDayHeaderView) c'è un modo per farlo abbastanza bene. CerchiamoUIView e NSLayoutConstraintin rettangoli rossi. Dato che conosciamo il loro ID in memoria , è abbastanza facile.

  • Interrompere l'utilizzo dell'app gerarchia di visualizzazione debug :

inserisci qui la descrizione dell'immagine

  • Trova l'UIView corretto:

inserisci qui la descrizione dell'immagine

  • Il prossimo è trovare NSLayoutConstraint a cui teniamo:

inserisci qui la descrizione dell'immagine

Come puoi vedere, i puntatori di memoria sono gli stessi. Quindi sappiamo cosa sta succedendo ora. Inoltre puoi trovareNSLayoutConstraint nella gerarchia di visualizzazione. Poiché è selezionato in Visualizza, è stato selezionato anche in Navigator.

inserisci qui la descrizione dell'immagine

Se necessario, puoi anche stamparlo sulla console utilizzando il puntatore di indirizzo:

(lldb) po 0x17dce920
<UIView: 0x17dce920; frame = (10 30; 300 24.5); autoresize = RM+BM; layer = <CALayer: 0x17dce9b0>>

Puoi fare lo stesso per ogni vincolo che il debugger ti indicherà :-) Ora decidi tu cosa farne.

  1. STAMPA MEGLIO (lo consiglio davvero in questo modo, questo è Xcode 7)

    • imposta un identificatore univoco per ogni vincolo nella tua vista:

inserisci qui la descrizione dell'immagine

  • crea una semplice estensione per NSLayoutConstraint :

SWIFT :

extension NSLayoutConstraint {

    override public var description: String {
        let id = identifier ?? ""
        return "id: \(id), constant: \(constant)" //you may print whatever you want here
    }
}

Objective-C

@interface NSLayoutConstraint (Description)

@end

@implementation NSLayoutConstraint (Description)

-(NSString *)description {
    return [NSString stringWithFormat:@"id: %@, constant: %f", self.identifier, self.constant];
}

@end
  • crealo di nuovo, e ora hai un output più leggibile per te:

inserisci qui la descrizione dell'immagine

  • una volta ottenuto il tuo id, puoi semplicemente toccarlo nel Trova Navigator :

inserisci qui la descrizione dell'immagine

  • e trovalo rapidamente:

inserisci qui la descrizione dell'immagine

COME SEMPLICE RISOLVERE QUESTO CASO?

  • prova a cambiare la priorità in 999per vincolo rotto.

Questo ha appena corretto il mio bug ... grazie mille. Come lo faresti per l'obiettivo c? Aggiungi una categoria?
Cheznead,

Grazie per la soluzione, ma posso usare l'estensione nell'obiettivo c?
dev.nikolaz,

Questo identificatore è uguale a accessibilityIdentifier disponibile su UIVview a livello di codice. In caso contrario, come si può impostare l'identificatore a livello di codice?
Arunabh Das,

@ No, non è lo stesso. Leggi questa risposta
Bartłomiej Semańczyk il

3
Mi piace il secondo modo e penso che sia il modo migliore per rintracciare il vincolo rotto
Antarix,

108

Il problema che stai riscontrando è che i NSAutoresizingMaskLayoutConstraints non dovrebbero essere presenti. Questo è il vecchio sistema di molle e montanti. Per sbarazzartene, esegui questo metodo su ogni vista che vuoi vincolare:

[view setTranslatesAutoresizingMaskIntoConstraints:NO];

5
quali sono alcuni dei motivi per cui una vista non appare affatto quando si imposta setTranslatesAutoresizingMaskIntoConstraints su NO?
topwik,

1
ad esempio, creo un SSBadgeView (UIView), aggiungo un subView imageView a SSBadgeView, quindi aggiungo SSBAdgeView come subview a UIReuseableView. Aggiungo alcuni vincoli a SSBadgeView e setTranslatesAutoresizingMaskIntoConstraints: NO su SSBadgeView. l'immagine subView di SSBadgeView è disposta come previsto ma il genitore SSBadgeView dell'immagine non è visibile da nessuna parte.
topwik,

1
Hai dimenticato di disabilitare TranslatesAutoresizingMaskIntoConstraints nelle tue viste secondarie secondarie
Softlion

Questo è ciò che accade quando imposto questa proprietà, drive.google.com/file/d/0BxuYs8WHXCF7bV9ndHFrQ0dMYVE/… Sto usando questa riga di codice: [self.contentView setTranslatesAutoresizingMaskIntoConstraints: NO]; for (vista UIView * in self.contentView.subviews) {[view setTranslatesAutoresizingMaskIntoConstraints: NO]; } In precedenza assomigliava a: drive.google.com/file/d/0BxuYs8WHXCF7OWlvZGQwN3FlbzQ/… Ha funzionato però, devo dire.
rptwsthi,

28

Fare attenzione a non utilizzare più di un vincolo nella stessa direzione e tipo.

Ad esempio: vincolo verticale per trascinamento = 15 e un altro è> = 10.

A volte, Xcode crea alcuni vincoli che non noti . Devi eliminare i vincoli ridondanti e l'avviso di registro scomparirà sicuramente.

inserisci qui la descrizione dell'immagine

Inoltre, puoi leggere e rilevare alcuni motivi, direttamente dal registro :

NSLayoutConstraint: 0xa338390 V: | - (15) - [UILabel: 0xa331260] (Nomi: '|': UILabel: 0xa330270)>

Questo possiamo leggere come un problema nel vincolo UILabel, sta portando un vincolo verticale lungo 15pt.

NSLayoutConstraint: 0x859ab20 H :-( 13) - | [UIView: 0x85a8fb0] ...

Questo sarebbe un vincolo orizzontale finale ecc.


6

Ho avuto un certo numero di queste eccezioni, il modo più semplice e veloce che ho trovato per risolverle è stato quello di trovare valori univoci nelle eccezioni che ho quindi cercato nel codice sorgente dello storyboard. Questo mi ha aiutato a trovare le viste effettive e i vincoli che causano il problema (utilizzo UserLabels significativi su tutte le viste, il che rende molto più semplice tenere traccia dei vincoli e delle viste) ...

Quindi, usando le eccezioni sopra, aprirei lo storyboard come "codice sorgente" in xcode (o un altro editor) e cerco qualcosa che posso trovare ...

<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]> 

.. questo sembra un vincolo verticale (V) su un UILabel con un valore di (17).

Guardando attraverso le eccezioni che trovo anche

<NSLayoutConstraint:0x72c22b0 V:[UILabel:0x72bf7c0]-(NSSpace(8))-[UIButton:0x886efe0]>

Che assomiglia a UILabel (0x72bf7c0) è vicino a un UIButton (0x886efe0) con una spaziatura verticale (8) ..

Spero che questo mi basti per trovare le viste specifiche nel codice sorgente dello storyboard (probabilmente cercando inizialmente "17" nel testo), o almeno alcuni probabili candidati. Da lì dovrei essere in grado di capire effettivamente quali visualizzazioni sono nello storyboard, il che renderà molto più facile identificare il problema (cercare il blocco "duplicato" o il conflitto che è in conflitto con vincoli di dimensioni).


"Uso userLabels significativi" - cosa sono i UserLabels in questo contesto? (ad esempio come impostarli)
Stripes

Nella sezione Documento della finestra di ispezione identità è presente un campo "Etichetta" .. che viene tradotto in un valore "userLabel" nel codice sorgente della storyboard.
C James,

Puoi anche impostarli facendo clic su una vista selezionata nel riquadro "Panoramica" a sinistra (un po 'come rinominare un file nel finder)
C James

1
Probabilmente la cosa migliore che ho letto riguardo alla risoluzione del temuto "Incapace di soddisfare simultaneamente i vincoli". dolore. Ho scoperto che l'oggetto mostrato a questo punto "Tenterà di recuperare rompendo il vincolo <NSLayoutConstraint:" di solito è il colpevole, e come dice C James, probabilmente un vincolo di altezza o larghezza che è in conflitto con vincoli di blocco. Ho trovato difficile rimuovere l'altezza ma poiché i vincoli erano corretti, l'altezza poteva essere ricavata dagli altri vincoli. L'aggiunta di un vincolo di altezza ha appena confuso il layout automatico, quindi è quello che cerco ora.
latenitecoder,

6

Ho avuto difficoltà a capire quali vincoli stavano causando questo errore. Ecco un modo più semplice per farlo.

Sto usando Xcode 6.1.1

  1. "Comando + A" per selezionare tutti gli UILabels, UIImages ecc.
  2. Fai clic su Editor -> Aggiungi> (Seleziona ...) su Superview
  3. fai di nuovo clic su Editor -> Risolvi problemi di layout automatico -> Aggiungi vincoli mancanti o Ripristina vincoli suggeriti. Dipende dal tuo caso.

5

Ho avuto questo problema perché il mio .xib file utilizzavano il layout automatico.

Nella finestra di ispezione dei file, prima scheda. Deselezionando "Usa autolayout" il problema è stato risolto.

ispettore file di autolayout


Quindi l'ho fatto e risolto il problema, ma un 'UIImageView' che avevo nella parte superiore dello schermo (che ho usato come barra di navigazione) è stato spostato nella parte inferiore dello schermo. Sai perché è successo?
dietbacon

1
Il layout automatico utilizza i vincoli per governare il layout degli oggetti. Poiché hai appena disattivato il completamento automatico, questi vincoli sono probabilmente scomparsi e quindi la posizione del tuo UIImageViewè cambiata. È necessario impostare nuovamente questa posizione, a livello di codice o tramite Interface Builder.
Stéphane Bruckert,

5

Ecco la mia esperienza e soluzione. Non ho toccato il codice

  1. Seleziona vista (UILabel, UIImage ecc.)
  2. Editor> Pin> (Seleziona ...) su Superview
  3. Editor> Risoluzione dei problemi di layout automatico> Aggiungi vincoli mancanti

4

usa rapidamente questo codice

view.translatesAutoresizingMaskIntoConstraints = false

1
Questa è una risposta rapida a una domanda con tag c obiettivo.
Tobi Nary,

2
@SmokeDispenser Ho già detto che si tratta di un codice rapido. e ha funzionato per me. rapido / obiettivo è avere SDK touch cacao comune.
Arun Kumar P,

2

Ho seguito domande e risposte SO da ogni query di ricerca. Ma sono tutti correlati con uno specifico.

Alla base, intendo, prima che tu scriva un formato (può essere semplice) ti darà degli avvertimenti.

Da iOS 8.0 le visualizzazioni predefinite sono classi di dimensioni. Anche se disabiliti le classi di dimensioni, conterrà comunque alcuni vincoli di layout automatico.

Quindi, se stai pianificando di impostare vincoli tramite codice usando VFL. Quindi devi prenderti cura di uno sotto la linea.

// Remove constraints if any.
[self.view removeConstraints:self.view.constraints];

Ho cercato molto in SO, ma la soluzione era nel codice di esempio Apple .

Quindi è necessario rimuovere i vincoli predefiniti prima di pianificare l'aggiunta di uno nuovo.


1

Per me il motivo principale di questo problema è che ho dimenticato di deselezionare AutoLayoutl' Xibeditor. In effetti, ho apportato molte modifiche al XIBcodice in.


1
 for(UIView *view in [self.view subviews]) {
    [view setTranslatesAutoresizingMaskIntoConstraints:NO];
}

Questo mi ha aiutato a catturare la vista causando il problema.


1

Nessuna delle risposte precedenti è utile nella mia situazione. Sto eseguendo XCode 10.1 e testando la mia app sul simulatore per un "iPad (5a generazione)". Il simulatore esegue iOS 12.1.

Ho una semplice vista di root nel mio storyboard, con due sottoview UITextField. Non ci sono assolutamente vincoli nello storyboard. E non ho oggetti UIButtonBarView nell'app o nello storyboard.

Nessun messaggio viene stampato all'avvio dell'app e stabilisce la vista principale. Nessuno quando il dispositivo simulato viene ruotato.

Ma nel simulatore, nel momento in cui faccio clic su uno dei campi di testo, l'estensione della tastiera sorge dalla parte inferiore dello schermo, sebbene non sia la tastiera completa, che sembra non apparire mai nel simulatore. Ma quanto segue viene stampato sul terminale:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
"<NSAutoresizingMaskLayoutConstraint:0x6000034e7700 h=--& v=--& UIKeyboardAssistantBar:0x7f9c7d714af0.height == 0   (active)>",
"<NSLayoutConstraint:0x6000034aba20 V:|-(0)-[_UIUCBKBSelectionBackground:0x7f9c7d51ec70]   (active, names: '|':_UIButtonBarButton:0x7f9c7d51de40 )>",
"<NSLayoutConstraint:0x6000034aba70 _UIUCBKBSelectionBackground:0x7f9c7d51ec70.bottom == _UIButtonBarButton:0x7f9c7d51de40.bottom   (active)>",
"<NSLayoutConstraint:0x6000034fb3e0 V:|-(0)-[_UIButtonBarStackView:0x7f9c7d715880]   (active, names: '|':UIKeyboardAssistantBar:0x7f9c7d714af0 )>",
"<NSLayoutConstraint:0x6000034fb750 V:[_UIButtonBarStackView:0x7f9c7d715880]-(0)-|   (active, names: '|':UIKeyboardAssistantBar:0x7f9c7d714af0 )>",
"<NSLayoutConstraint:0x6000034abc00 'UIButtonBar.maximumAlignmentSize' _UIButtonBarButton:0x7f9c7d51de40.height == UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide'.height   (active)>",
"<NSLayoutConstraint:0x6000034d7cf0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide']-(9)-|   (active, names: '|':_UIButtonBarStackView:0x7f9c7d715880 )>",
"<NSLayoutConstraint:0x6000034d7c50 'UIView-topMargin-guide-constraint' V:|-(10)-[UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide']   (active, names: '|':_UIButtonBarStackView:0x7f9c7d715880 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000034aba70 _UIUCBKBSelectionBackground:0x7f9c7d51ec70.bottom == _UIButtonBarButton:0x7f9c7d51de40.bottom   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

Mi sembra certamente che tutto ciò non abbia nulla a che fare con la mia app, e tutto ciò che riguarda il modo in cui Apple sta creando la propria vista da tastiera, anche con la mia piccola estensione dichiarata combinata con essa.

Quindi la domanda rimane, c'è qualcosa che io come sviluppatore di app sono responsabile di fare (presumendo che sia un mucchio di cose a cui vale la pena occuparsi) o è solo il problema / bug di Apple?

FWIW, questo messaggio di problema di vincolo non si verifica quando si simula un modello iPad più recente, come iPad Pro da 12,9 pollici (3a generazione). Ma il messaggio viene visualizzato quando si simula un iPad Pro da 9,7 pollici ". Tutti affermano di utilizzare iOS 12.1.


1

Ricevo lo stesso errore, ma solo su una vista specifica, quando tocco il primo campo di testo, quindi il campo di testo successivo in basso.

Sto scrivendo in SwiftUI per iOS 13.4

 Unable to simultaneously satisfy constraints.
        Probably at least one of the constraints in the following list is one you don't want. 
        Try this: 
            (1) look at each constraint and try to figure out which you don't expect; 
            (2) find the code that added the unwanted constraint or constraints and fix it. 
    (
        "<NSLayoutConstraint:0x2809b6760 'assistantHeight' TUISystemInputAssistantView:0x105710da0.height == 44   (active)>",
        "<NSLayoutConstraint:0x2809ccff0 'assistantView.bottom' TUISystemInputAssistantView:0x105710da0.bottom == _UIKBCompatInputView:0x10525ae10.top   (active)>",
        "<NSLayoutConstraint:0x2809cccd0 'assistantView.top' V:|-(0)-[TUISystemInputAssistantView:0x105710da0]   (active, names: '|':UIInputSetHostView:0x105215010 )>",
        "<NSLayoutConstraint:0x2809ca300 'inputView.top' V:|-(0)-[_UIKBCompatInputView:0x10525ae10]   (active, names: '|':UIInputSetHostView:0x105215010 )>"
    )

    Will attempt to recover by breaking constraint 
    <NSLayoutConstraint:0x2809ccff0 'assistantView.bottom' TUISystemInputAssistantView:0x105710da0.bottom == _UIKBCompatInputView:0x10525ae10.top   (active)>

    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
    The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

0

Stavo anche riscontrando lo stesso problema di rompere i vincoli nel registro, per un viewCircle in xib. Ho quasi provato tutto quanto sopra elencato e niente funzionava per me. Quindi ho provato a cambiare la priorità del vincolo Height che si stava rompendo nel registro (confermato aggiungendo un identificatore per i vincoli sullo xib) inserire qui la descrizione dell'immagine


-1

Una cosa a cui fare attenzione (almeno questo mi ha fatto inciampare) era che stavo rimuovendo il vincolo dalla visione sbagliata. Il vincolo che stavo cercando di rimuovere non era un vincolo secondario della mia visione, quindi quando l'ho fatto

myView.removeConstraint(theConstraint)

in realtà non stava rimuovendo nulla perché avevo bisogno di chiamare

myView.superView.removeConstraint(theConstraint)

dal momento che il vincolo era tecnicamente un vincolo di pari livello secondo me.


-4

veloce 4

Aggiungo solo questa riga in viewDidLoad e lavoro bene con me.

view.removeConstraints(view.constraints)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.