2014-09-02 5 views
29

appena iniziato l'apprendimento iOS AutoLayout, Interface Builder molto semplice, ma quando cerco di archiviare la stessa cosa sul codiceAutoLayout, in grado di soddisfare contemporaneamente i vincoli

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(==2)-[_nextKeyboardButton]-(==2)-[_numPadButton]-(==2)-[_spaceButton]-(==2)-[_returnButton]-(==2)-|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(_nextKeyboardButton,_numPadButton,_spaceButton,_returnButton)]]; 

solleva un'eccezione,

Impossibile soddisfare contemporaneamente i vincoli.

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) 
(
"<NSLayoutConstraint:0x6000000966c0 H:|-(2)-[UIButton:0x7fe4f1d1c760'Next'] (Names: '|':UIInputView:0x7fe4f1f04d00)>", 
"<NSLayoutConstraint:0x600000096710 H:[UIButton:0x7fe4f1d1c760'Next']-(2)-[UIButton:0x7fe4f1d1d1d0'123']>", 
"<NSLayoutConstraint:0x600000096760 H:[UIButton:0x7fe4f1d1d1d0'123']-(2)-[UIButton:0x7fe4f1d1d6f0'Space']>", 
"<NSLayoutConstraint:0x6000000967b0 H:[UIButton:0x7fe4f1d1d6f0'Space']-(2)-[UIButton:0x7fe4f1d1d8d0'Return']>", 
"<NSLayoutConstraint:0x600000096800 H:[UIButton:0x7fe4f1d1d8d0'Return']-(2)-| (Names: '|':UIInputView:0x7fe4f1f04d00)>", 
"<NSLayoutConstraint:0x600000096e40 'UIView-Encapsulated-Layout-Width' H:[UIInputView:0x7fe4f1f04d00(0)]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000000967b0 H:[UIButton:0x7fe4f1d1d6f0'Space']-(2)-[UIButton:0x7fe4f1d1d8d0'Return']> 

Tutti 4 tasti .translatesAutoresizingMaskIntoConstraints = NO;

Mi chiedo cosa c'è che non va? aiuto è molto apprezzato :)

FYI: Io lavoro su iOS 8 SDK

+1

Sembra una serie di vincoli perfettamente logica. Mi sono battuto la testa per qualcosa di simile negli ultimi pochi GIORNI. Btw, @Chamira Fernando ci sono altri vincoli di larghezza sui pulsanti? Dimensioni del contenuto intrinseco ecc.? Hai provato a impostare compressionResistancePriority o contentHuggingPriority su valori alti o bassi? Vedi cosa succede? –

+3

Il motivo dell'errore di vincolo è ovviamente causato dalla larghezza di 'UIView-Encapsulated-Layout-Width' pari a 0. Dove si trova' UIInputView'? –

+0

Silly me - Non l'ho visto (0). Ho avuto lo stesso problema. È un UIInputView fornito da un UIInputViewController - vista root di un'estensione Keyboard (iOS8). Non so perché vorrebbe una larghezza di 0, considerando il comportamento predefinito (secondo i documenti) dovrebbe essere quello di attenersi alla larghezza dello schermo. –

risposta

2

Secondo la tua domanda quello che ho capito che si è creato il controllo in pennino e si sta cercando di cambiare direttamente è vincoli dalla tua classe.

Ciò che è possibile fare qui è impostare i vincoli in nib per il controller di visualizzazione e quindi associarlo alla classe e utilizzare oggetti di vincoli. Oppure puoi creare la visualizzazione a livello di codice e impostare direttamente i vincoli.

// È inoltre necessario verificare che se è necessario “translatesAutoresizingMaskIntoConstraints” se “SI - superview della vista guarda maschera il ridimensionamento automatico della vista, produce vincoli che lo implementano, e aggiunge questi vincoli a se stesso (la superview). ”e se‘NO -. superview della vista non guarda maschera il ridimensionamento automatico della vista, e non produce i vincoli che lo implementano’

ho anche avuto stesso problema e ho fissato come segue

 [_nextKeyboardButton setTranslatesAutoresizingMaskIntoConstraints:YES]; 
    _numPadButton.translatesAutoresizingMaskIntoConstraints = YES; 
    [_numPadButton updateConstraints]; 
    [_nextKeyboardButton updateConstraints]; 

    NSArray *constraints2 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"H:|-57-[_nextKeyboardButton(96)]" 
          options:0 
          metrics:nil 
          views:NSDictionaryOfVariableBindings(_nextKeyboardButton)]; 

    [self.view addConstraints:constraints2]; 

    NSArray *constraints4 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-123-[_nextKeyboardButton(30)]" 
          options:0 
          metrics:nil 
          views:NSDictionaryOfVariableBindings(_nextKeyboardButton)]; 

    [self.view addConstraints:constraints4]; 

    NSArray *constraints1 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"H:|-207-[_numPadButton(58)]" 
          options:0 
          metrics:nil 
          views:NSDictionaryOfVariableBindings(_numPadButton)]; 

    [self.view addConstraints:constraints1]; 

    NSArray *constraints3 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-123-[_numPadButton(30)]" 
          options:0 
          metrics:nil 
          views:NSDictionaryOfVariableBindings(_numPadButton)]; 

    [self.view addConstraints:constraints3]; 

// Create Controls or view programmatically. 

UILabel *label = [UILabel new]; 
    label.text = @"This is a Label"; 
    label.font = [UIFont systemFontOfSize:18]; 
    label.backgroundColor = [UIColor lightGrayColor]; 
    label.translatesAutoresizingMaskIntoConstraints = NO; 
    [self.view addSubview:label]; 

    NSArray *constraints = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-offsetTop-[label(100)]" 
          options:0 
          metrics:@{@"offsetTop": @100} 
          views:NSDictionaryOfVariableBindings(label)]; 
    [self.view addConstraints:constraints]; 

    UIView *spacer1 = [UIView new]; 
    spacer1.translatesAutoresizingMaskIntoConstraints = NO; 
    [spacer1 setBackgroundColor:[UIColor redColor]]; 
    [self.view addSubview:spacer1]; 

    UIView *spacer2 = [UIView new]; 
    spacer2.translatesAutoresizingMaskIntoConstraints = NO; 
    [spacer2 setBackgroundColor:[UIColor greenColor]]; 
    [self.view addSubview:spacer2]; 

    NSArray *constraints1 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-offsetTop-[spacer1(100)]" 
          options:0 
          metrics:@{@"offsetTop": @100} 
          views:NSDictionaryOfVariableBindings(spacer1)]; 

    [self.view addConstraints:constraints1]; 

    NSArray *constraints2 = [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|-offsetTop-[spacer2(100)]" 
          options:0 
          metrics:@{@"offsetTop": @100} 
          views:NSDictionaryOfVariableBindings(spacer2)]; 

    [self.view addConstraints:constraints2]; 

    [self.view addConstraints:[NSLayoutConstraint 
           constraintsWithVisualFormat:@"H:|[spacer1]-10-[label]-20-[spacer2(==spacer1)]|" 
           options:0 
           metrics:nil 
           views:NSDictionaryOfVariableBindings(label, spacer1, spacer2)]]; 

Quindi, quando usi AutoLayout, dovresti mai impostare direttamente la cornice di una vista. I vincoli sono usati per fare questo per te. Normalmente se si desidera impostare i propri vincoli in una vista, è necessario sovrascrivere il metodo updateConstraints dei propri UIViews. Assicurati che le visualizzazioni del contenuto per il controller di pagina consentano di ridimensionare i bordi, poiché verranno ridimensionati per adattarsi alla cornice della vista pagina. I tuoi vincoli e la configurazione della vista dovranno tenerne conto, altrimenti otterrai degli errori di vincolo insoddisfacenti.

https://developer.apple.com/library/mac/documentation/userexperience/conceptual/AutolayoutPG/AutoLayoutConcepts/AutoLayoutConcepts.html#//apple_ref/doc/uid/TP40010853-CH14-SW1 È inoltre possibile fare riferimento al link sopra di Apple per approfondire lo studio e se si continua ad affrontare il problema, proverò a provare il mio livello migliore per risolvere il problema.

8

Ho dovuto confrontarmi con un problema simile quando stavo cercando di creare manualmente tutti i vincoli di layout automatico (in Swift, usando Snappy - una porta di Masonry a Swift) in un controller di visualizzazione basato su uno Storyboard.

Per qualche motivo, Xcode genera il proprio set predefinito di vincoli di layout automatico su un NIB in fase di compilazione. Questo è il motivo per cui non ho potuto aggiungere altri vincoli manuali, perché erano in conflitto con quelli aggiunti automaticamente.

ho risolto questo modo seguente:

  • aprire lo Storyboard controller che si sta manipolazione.

  • Selezionare il controller della vista e selezionare Editor> Risoluzione automatica problemi di layout> Tutti Visualizzazioni in [] View Controller> Aggiunta di vincoli mancanti dal menu:

enter image description here

(Questa volontà assicurati che non vengano creati ulteriori vincoli di tempo di costruzione e che tutti i vincoli siano ora visibili)

  • Seleziona tutti i vincoli dal controller della vista:

enter image description here

  • Controllare dal pannello di destra la seguente casella di controllo: Segnaposto - Togliere al momento della compilazione:

enter image description here

Ora è possibile aggiungere manualmente tutti i vincoli di layout automatico nel codice.

+1

Questo ha risolto perfettamente il problema per me. – aframe

+0

Mi sono imbattuto in un problema simile, ho sette UIButton allineati in fila. In StoryBoard va tutto bene, ma quando lo costruisco, ho ottenuto un sacco di eccezioni "Incapace di soddisfare simultaneamente i vincoli", ma il simulatore ha un bell'aspetto. Mi chiedo se dovrei fare qualcosa per loro o no? E se lo faccio, non posso usare l'editor per risolvere problemi di vincoli perché non ce ne sono nel mio StoryBoard. – Liumx31

77

Il modo più semplice come trovare i vincoli insoddisfacibile:

  • impostato identificatore univoco per ogni vincolo a suo avviso:

enter image description here

  • creare 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 
  • costruire ancora una volta, e ora si dispone di output più leggibile per voi:

enter image description here

  • una volta ottenuto il vostro id è possibile semplice rubinetto nel vostro Trova Navigator:

enter image description here

  • e rapidamente trovano:

enter image description here

COME SEMPLICE FISSARE QUELLA CAUSA?

  • provare a cambiare la priorità -999 per vincolo rotto.

vedere la risposta correlata qui: Unable to simultaneously satisfy constraints, will attempt to recover by breaking constraint

+9

un consiglio incredibile. – Fattie

+1

Questa è la cosa più utile che abbia mai letto per il debug dei problemi di vincoli. Mani giù. Grazie! – Xeaza

+0

ty, questo lavoro piacevole –

3

Può non essere così difficult.The output della console messaggio dice che i vincoli del UIButton redefined.It significa proprio così si mette un vincolo che limita la Height e la Width del pulsante, ma inutilmente hai messo un'altra restrizione che il pulsante ha un Aspect Ratio. In questa condizione Xcode non può assicurarsi quale vincolo da seguire, in modo che tu possa vedere questo messaggio di debug nella console.

Ci sono due modi utile per me:

  1. analizzare i vincoli visualizzati nella console, e tenta di eliminare uno o più vincoli.

2.Se si utilizza storyboard o Xib, selezionare un vincolo -> Mostra l'ispettore attributi -> modificare la priorità di alcuni vincoli.


Ancora una cosa ...

È possibile seguire la article di Jason Jarrett. Aggiungi un punto di interruzione del simbolo per assicurarti quale vista farà accadere l'errore.

1

Nel caso in cui nessun altro si imbatte in questo, un modo semplice per controllare visivamente per problemi con i vincoli è presente sul sito (è davvero utile!):

http://www.wtfautolayout.com

Ecco il progetto Github nel caso in cui il sito va giù: https://github.com/johnpatrickmorgan/wtfautolayout

+0

Mentre questo link può rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia – slfan