2013-07-29 13 views
5

Mam dwa kontrolery widoku, nadrzędny i podrzędny.Ograniczenia trybu automatycznego i kontrolera podrzędnego

więc w metodzie viewDidLoad I wykonaj następujące czynności:

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 
// 

Więc w zasadzie to, co się dzieje, że updateViewConstraints nazywa na ChildViewController przed ograniczeniami regulatora rodzic stosuje, więc w rzeczywistości self.view.frame == CGRectZero, dokładnie tak samo jak podano w niestandardowa metoda loadView w ChildViewController.

translatesAutoresizingMaskIntoConstraints wszystkie ustawione na NO dla wszystkich widoków.

Jaki jest właściwy sposób ustawiania ograniczeń w tym przypadku, aby ChildViewController zaktualizował swoje ograniczenia po rodzicu?

Aktualny log z obu kontrolerów jest dość frustrujące, nie rozumiem jak updateViewConstraints może być wywołana przed viewWillLayoutSubviews:

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

Musisz pokazać kod, w którym faktycznie dodajesz swoje ograniczenia, w przeciwnym razie trudno powiedzieć, co jest nie tak. – Maarten

+0

@Maarten Rozwiązałem problem i wysłałem odpowiedź poniżej, nie jestem pewien, czy to rozwiązanie, którego szukałem, wydaje się błędne, ale działa. Przepraszam, że nie mogę opublikować kodu, to za dużo kodu ... – Andy

Odpowiedz

1

Zgodnie z the following link, przeniosłem tworzenie wiązań do viewWillLayoutSubviews, jest to miejsce, w którym widoki są ustawione prawidłowo. Czuję, że ta odpowiedź pomija wyjaśnienie, dlaczego kontroler widoku podglądu kontrolek podrzędnych jest wywoływany przed nadrzędnym kontrolerem widoku, lub może to tylko jakiś błąd w moim kodzie, ale to obejście rozwiązuje problem ...

1
  1. Myślę, że metoda layoutIfNeeded będzie działać tylko wtedy, gdy wcześniej nazywana setNeedsLayout. Jeśli użyjesz zamiast tego setNeedsLayout, system będzie wiedział o aktualizacji w odpowiednim czasie. Spróbuj zmienić to w swoim kodzie.

  2. Po dodaniu wiązań do widoku widok ten powinien automatycznie układać swoje widoki podrzędne, aby uwzględnić nowe ograniczenia. Nie powinno być potrzeby dzwonienia pod numer setNeedsLayout, chyba że coś się zmieniło od czasu dodania ograniczeń. Czy dodajesz ograniczenia do widoku, a jeśli tak, to czy dodajesz je do odpowiedniego widoku?

  3. Jedno można spróbować jest do podklasy UIView tak, że pojawi się komunikat dziennika, gdy ChildViewController.view lub ParentViewController.view wykonuje świeży układ:

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

Może pokaże coś o tym, kiedy swoje poglądy są (lub nie są) układają swoje subviews.

+0

Dobrze, layoutIfNeeded tak naprawdę nie zmienia niczego, jeśli setNeedsUpdateConstraints nie było wcześniej używane. To jest mój dziennik w tej chwili: ChildViewController :: updateViewConstraints. RECT: {{0, 0}, {0, 0}} ParentViewController :: updateViewConstraints ChildViewController_view :: layoutSubviews – Andy

+0

Dlatego kontroler Child zaktualizowany najpierw, a następnie rodzic. Wszystkie ograniczenia utworzone w viewDidLoad, więc nie rozumiem dokładnie, jak to jest możliwe. – Andy

3

Mam podobną sytuację, w której dodaję kontroler dziecko do widocznego kontrolera (popup).

Definiuję kontrolkę widoku podrzędnego w konstruktorze interfejsów. Jest to metoda viewDidLoad po prostu wywołuje setTranslatesAutoresizingMaskIntoConstraints: NIE

Następnie definiuję tę metodę na kontrolerze podrzędnym, który pobiera parametr UIViewController, który jest rodzicem. Ta metoda dodaje się do danego macierzystego widoku kontrolera i określa swoje własne ograniczenia:

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

następnie wewnątrz rodzica UIViewController (ten, który jest już wyświetlana), gdy chcę, aby wyświetlić moje dziecko podręczne widoku kontroler wywołuje :

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

można zdefiniować ograniczenia co chcesz oglądać sterownika podrzędnego podczas dodawania go do widoku kontrolera nadrzędnego.

Powiązane problemy