2013-07-29 6 views
5

Ich habe zwei View-Controller, Eltern und Kind.Automatische Anordnung Einschränkungen und Kind-View-Controller

So in der viewDidLoad Methode kann ich folgendes:

ChildViewController* childViewController = [[ChildViewController alloc] init]; 

[self addChildViewController:childViewController]; 

// ChildViewController sets his own constraints in viewDidLoad 
[self.view addSubview:childViewController.view]; 

[childViewController didMoveToParentViewController:self]; 

// 
// setup constraints to expand childViewController.view to 
// fill the size of parent view controller 
// 

Also im Grunde, was passiert ist, dass updateViewConstraints auf ChildViewController anwenden, bevor Eltern Controller Einschränkungen genannt wird, so in der Tat self.view.frame == CGRectZero, genau das gleiche wie ich angegeben in benutzerdefinierte loadView Methode in ChildViewController.

translatesAutoresizingMaskIntoConstraints alle NO für alle Ansichten festgelegt.

Was ist der richtige Weg, um Auslegungsbeschränkungen in diesem Fall so ChildViewController aktualisiert seine Zwänge nach Elternteil?

Aktuelles Protokoll von beiden Controllern ist ziemlich frustrierend, ich verstehe nicht, wie updateViewConstraints kann vor viewWillLayoutSubviews aufgerufen werden:

App[47933:c07] ChildViewController::updateViewConstraints. RECT: {{0, 0}, {0, 0}} 
App[47933:c07] ParentViewController::updateViewConstraints 
App[47933:c07] ChildViewController:viewWillLayoutSubviews. RECT: {{0, 0}, {984, 454}} 
App[47933:c07] ChildViewController:viewDidLayoutSubviews. RECT: {{0, 0}, {984, 454}} 
+0

Sie müssen den Code anzeigen, wo Sie tatsächlich Ihre Einschränkungen hinzufügen, sonst ist es schwer zu sagen, was los ist. – Maarten

+0

@Maarten Ich habe das Problem gelöst und die Antwort unten gepostet, nicht sicher, dass es die Lösung ist, nach der ich gesucht habe, es scheint falsch, aber es funktioniert. Sorry, dass ich den Code nicht posten kann, es ist zu viel Code ... – Andy

Antwort

1

Gemäß the following link habe ich Constraints Creation zu viewWillLayoutSubviews verschoben, das ist der Ort, an dem Ansichtsgrenzen ordnungsgemäß festgelegt sind. Ich glaube, diese Antwort vermisst die Erklärung, warum Childview controls updateViewConstraints vor dem übergeordneten View-Controller aufgerufen wird, oder vielleicht ist es nur ein Fehler in meinem Code, aber diese Lösung löst das Problem ...

1
  1. Ich denke, die layoutIfNeeded Methode funktioniert nur, wenn Sie vorher setNeedsLayout genannt haben. Wenn Sie stattdessen setNeedsLayout verwenden, kann das System zu einem geeigneten Zeitpunkt aktualisieren. Versuchen Sie, das in Ihrem Code zu ändern.

  2. Wenn Sie Einschränkungen im Hinblick hinzufügen, sollte diese Ansicht Layout automatisch wieder seine Subviews für die neuen Einschränkungen zu berücksichtigen. Es sollte nicht erforderlich sein, setNeedsLayout aufzurufen, es sei denn, es hat sich etwas geändert, seit Sie die Einschränkungen hinzugefügt haben. Fügen Sie die Einschränkungen zu einer Ansicht hinzu und wenn ja: fügen Sie sie der rechten Ansicht hinzu?

  3. Eine Sache, die Sie versuchen können, ist UIView so zu Unterklasse, dass Sie eine Log-Nachricht sehen, wenn die ChildViewController.view oder ParentViewController.view ein frisches Layout führt:

    -(void) layoutSubviews { 
        [super layoutSubviews]; 
        NSLog(@"layoutSubviews was called on the following view: %@", [view description]); 
    } 
    

Vielleicht etwas, wenn Sie Ihre Ansichten offenbaren sind (oder sind nicht) Layout ihre Subviews.

+0

Richtig, layoutIfNeeded ändert nichts wirklich, wenn setNeedsUpdateConstraints vorher nicht verwendet wurde. Das ist mein Protokoll im Moment: ChildViewController :: updateViewConstraints. RECT: {{0, 0}, {0, 0}} ParentViewController :: updateViewConstraints ChildViewController_view :: layoutSubviews – Andy

+0

So Kind Controller zuerst aktualisiert, dann Eltern. Alle Einschränkungen, die in viewDidLoad erstellt wurden, daher verstehe ich nicht genau, wie das möglich ist. – Andy

3

Ich habe eine ähnliche Situation, wo ich ein hinzufügen Kind-Controller zu einem sichtbaren Controller (ein Popup).

definiere ich das Kind View-Controller in Interface Builder. Es ist viewDidLoad Methode ruft nur setTranslatesAutoresizingMaskIntoConstraints: NO

Dann definiere ich diese Methode auf der Kind-Controller, die einen UIViewController-Parameter, der die Eltern ist. Diese Methode fügt sich in die gegebenen Eltern-View-Controller und legt seine eigene Einschränkungen:

- (void) addPopupToController:(UIViewController *)parent { 
    UIView *view = [self view]; 
    [self willMoveToParentViewController:parent]; 
    [parent addChildViewController:self]; 
    [parent.view addSubview:view]; 
    [self didMoveToParentViewController:parent]; 

    NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[view]-0-|" 
                      options:0 
                      metrics:nil 
                       views:NSDictionaryOfVariableBindings(view)]; 
    [parent.view addConstraints:horizontalConstraints]; 

    NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[view]-0-|" 
                      options:0 
                      metrics:nil 
                      views:NSDictionaryOfVariableBindings(view)]; 
    [parent.view addConstraints:verticalConstraints]; 
} 

dann innerhalb des übergeordneten UIViewController (derjenige, der bereits angezeigt wird), wenn ich will mein Kind Popup-View-Controller angezeigt werden ruft :

PopUpNotificationViewController *popup = [[self storyboard] instantiateViewControllerWithIdentifier:@"NotificationPopup"]; 
[popup addPopupToController:self]; 

können Sie definieren, was Einschränkungen, die Sie auf dem Kinder Controllers wollen, wenn es um den übergeordneten Controller Ansicht hinzufügen.