2013-03-11 13 views
11

Sto provando a utilizzare l'autolayout nella mia app iOS a livello di programmazione. Ho un semplice controller di vista con questo codice initUso dei vincoli di autolayout programmaticamente

UIView *innerView = [[UIView alloc] initWithFrame:self.view.bounds]; 

UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
[button1 setFrame:CGRectMake(50, 50, 150, 50)]; 
[button1 setTitle:@"button1" forState:UIControlStateNormal]; 

UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
[button2 setFrame:CGRectMake(250, 50, 150, 50)]; 
[button2 setTitle:@"button2" forState:UIControlStateNormal]; 

[innerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[button1][button2(==button1)]|" options:NSLayoutFormatAlignAllBaseline metrics:0 views:NSDictionaryOfVariableBindings(button1, button2)]]; 

[innerView addSubview:button1]; 
[innerView addSubview:button2]; 
[self.view addSubview:innerView]; 

Ma quando sto cercando di eseguire questo, sto ottenendo questo errore:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse constraint format: 
Unable to interpret '|' character, because the related view doesn't have a superview 
|[button1][button2(==button1)]| 
      ^' 

Cosa c'è che non va?

E quando sto cercando di rimuovere i tubi in constraintsWithVisualFormat, sto ottenendo questo avvertimento:

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:0x716be10 h=--& v=--& UIRoundedRectButton:0x71631f0.midX == + 325>", 
    "<NSAutoresizingMaskLayoutConstraint:0x7169940 h=--& v=--& H:[UIRoundedRectButton:0x715fb80(150)]>", 
    "<NSAutoresizingMaskLayoutConstraint:0x7169860 h=--& v=--& UIRoundedRectButton:0x715fb80.midX == + 125>", 
    "<NSLayoutConstraint:0x7164cd0 UIRoundedRectButton:0x71631f0.width == UIRoundedRectButton:0x715fb80.width>", 
    "<NSLayoutConstraint:0x7164940 H:[UIRoundedRectButton:0x715fb80]-(0)-[UIRoundedRectButton:0x71631f0]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7164940 H:[UIRoundedRectButton:0x715fb80]-(0)-[UIRoundedRectButton:0x71631f0]> 

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. 

E come conseguenza di questo, i miei vincoli non hanno alcun effetto a tutti. Cosa sto sbagliando?

risposta

34

si hanno tre problemi:

primo luogo, è necessario optare-in a vincoli in base di layout sulle tue entrambi il pulsante subviews

[button1 setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[button2 setTranslatesAutoresizingMaskIntoConstraints:NO]; 

Questo permetterà di eliminare gli errori NSAutoresizingMaskLayoutConstraint. Ora puoi capire cosa sta succedendo con i vincoli di layout.

In secondo luogo, è necessario addSubview prima di aggiungere i vincoli. Stai chiamando addContraints su innerView prima che button1 e button2 siano sottoview di innerview.

In terzo luogo, è necessario specificare (anche se i documenti indicano che è facoltativo) se la stringa di layout è verticale o orizzontale. @"H:|[button1][button2(==button1)]|". Vorrete anche un vincolo verticale come @"V:[button1]|" che allinei button1 alla fine di innerview e poiché avete linee di riferimento allineate sui pulsanti, seguirà button2.

+1

Sì, 'setTranslatesAutoresizingMaskIntoConstraints: NO' mi ha aiutato a sbarazzarsi di questi errori. Ma come risultato sto ottenendo button2 allineato all'angolo in alto a sinistra (button1 non è visibile), e ancora non posso ancora usare pipe in 'visualFormat'. Hai idea del perché l'errore dice che la vista correlata non ha una superview? 'Self.view' di UIViewController è la superview del mio' innerView', non è vero? – bulbform

+2

"vista correlata non ha una superview" è perché si sta aggiungendo un vincolo che coinvolge una vista che non è stata ancora inserita nella gerarchia della vista. Sposta gli addConstraints: chiama dopo tutte le chiamate ad addSubview :. – escrafford

+0

grazie, quando ho spostato il blocco di codice con i vincoli sotto le istruzioni di 'addSubview', errore su 'incapace di interpretare pipe' era scomparso e ho un layout simile a quello che volevo) Grazie, il problema è risolto) – bulbform

2

Tanto per la cronaca: l'eccezione relativa alla superview mancante ottiene già innescato da constraintsWithVisualFormat non

Problemi correlati