2013-03-11 1 views
11

Ich versuche, automatisches Layout in meiner iOS-App programmgesteuert zu verwenden. Ich habe einen einfachen View-Controller mit diesem Init-CodeVerwenden von automatischen Layout-Einschränkungen programmgesteuert

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]; 

Aber wenn ich dies zu laufen bin versucht, erhalte ich diese Fehlermeldung:

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)]| 
      ^' 

Was ist falsch daran?

Und wenn ich versuche, Rohre in constraintsWithVisualFormat zu entfernen, erhalte ich diese Warnung:

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. 

Und als Folge davon haben meine Zwänge überhaupt keine Wirkung. Was mache ich falsch?

Antwort

34

Sie haben drei Probleme:

Zuerst müssen Sie das Layout basiert contraints auf beide Ihre Schaltfläche Subviews Opt-in

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

Dies wird der NSAutoresizingMaskLayoutConstraint Fehler loszuwerden. Jetzt können Sie sehen, was mit Ihren Layout-Einschränkungen passiert.

Zweitens müssen Sie addSubview vor dem Hinzufügen der Einschränkungen. Sie rufen addContraints auf InnerView, bevor Button1 und Button2 Unteransichten von Innerview sind.

Drittens sollten Sie angeben, ob die Layoutzeichenfolge vertikal oder horizontal ist (obwohl die Dokumente angeben, dass es optional ist). @"H:|[button1][button2(==button1)]|". Sie möchten auch eine vertikale Einschränkung wie @"V:[button1]|", die Button1 an den unteren Rand von innerview ausrichten würde und weil Sie Baselines auf den Schaltflächen ausgerichtet haben, folgt Button2.

+1

Ja, 'setTranslatesAutoresizingMaskIntoConstraints: NO' half mir loswerden diese Fehler zu bekommen. Aber als Ergebnis bekomme ich Button2 in der oberen linken Ecke ausgerichtet (Button1 ist nicht sichtbar), und dennoch kann ich noch keine Pipes in 'VisualFormat' verwenden. Haben Sie eine Idee, warum der Fehler sagt, dass die zugehörige Ansicht keine Superview hat? UIViewControllers 'self.view' ist Superview von meiner' inneren Ansicht', oder? – bulbform

+2

"Die verknüpfte Ansicht hat keine Superansicht" liegt daran, dass Sie eine Integritätsbedingung hinzufügen, die eine Ansicht enthält, die noch nicht in die Ansichtshierarchie eingefügt wurde. Verschieben Sie addConstraints: call nach allen Aufrufen von addSubview :. – escrafford

+0

danke, wenn ich Codeblock mit Einschränkungen unter 'addSubview' Anweisungen verschoben, Fehler über 'nicht interpretieren Rohr' war verschwunden und ich habe Layout ähnlich wie ich es wollte) Danke, das Problem ist gelöst) – bulbform

2

Nur für das Protokoll: die Ausnahme, die fehlenden Super über wird bereits ausgelöst durch constraintsWithVisualFormat nicht