2013-05-28 10 views
7

Mam kontroler widoku, który jest właścicielem pojedynczego widoku niestandardowego; widok niestandardowy rysuje planszę za pomocą Core Graphics. (Żadne inne subviews nie są zaangażowane.)Dlaczego mój widok z podglądem z podziałem zmniejsza się, gdy jest prezentowany modalnie (przy użyciu automatycznego układu)?

Konfiguruję wiązania Auto Layout tak, aby plansza wypełniała swój podgląd. Kiedy ustawiam kontroler widoku jako kontroler widoku root, to plansza gry (i superview) wypełnia ekran, tak jak mam zamiar. Jednak gdy modularnie przedstawiam kontroler widoku, plansza gry (i superview) zmniejsza się do nic/minimum, a śledzenie układu automatycznego zgłasza, że ​​układ jest niejednoznaczny.

Napisałem uproszczony przypadek testowy, aby zilustrować pytanie.

Oto mój BoardViewController, który ma widok najwyższego poziomu z zielonym tłem, ale tworzy pojedyncze ekspansywne wyeksponowanie z czerwonym tłem. Chciałbym zobaczyć na ekranie wszystkie czerwone gdy kontroler widoku przejmuje:

- (void)loadView 
{ 
    UIView *mainView = [[UIView alloc] init]; 
    mainView.translatesAutoresizingMaskIntoConstraints = NO; 
    mainView.backgroundColor = [UIColor greenColor]; 

    UIView *subView = [[UIView alloc] init]; 
    subView.translatesAutoresizingMaskIntoConstraints = NO; 
    subView.backgroundColor = [UIColor redColor]; 

    [mainView addSubview:subView]; 
    self.view = mainView; 

    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(subView); 
    NSArray *c1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subView(>=10)]|" 
                 options:0 
                 metrics:nil 
                  views:viewsDictionary]; 
    NSArray *c2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subView(>=10)]|" 
                 options:0 
                 metrics:nil 
                  views:viewsDictionary]; 
    [self.view addConstraints:c1]; 
    [self.view addConstraints:c2]; 
} 

Jeżeli ustawić to jako moim zdaniem główny kontroler, to widzę, mój miły czerwona plansza wypełnienie ekranu. Jednak gra planszowa kurczy się do minimalnej kwadrat 10x10 gdy przedstawiam BoardViewController z innej RootViewController:

- (void)loadView 
{ 
    UIView *rootView = [[UIView alloc] init]; 
    rootView.translatesAutoresizingMaskIntoConstraints = NO; 

    UIButton *presentButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    presentButton.translatesAutoresizingMaskIntoConstraints = NO; 
    [presentButton setTitle:@"Present" forState:UIControlStateNormal]; 
    [presentButton addTarget:self 
        action:@selector(present:) 
      forControlEvents:UIControlEventTouchUpInside]; 

    [rootView addSubview:presentButton]; 
    self.view = rootView; 

    [rootView addConstraint:[NSLayoutConstraint constraintWithItem:presentButton 
                 attribute:NSLayoutAttributeCenterX 
                 relatedBy:NSLayoutRelationEqual 
                  toItem:rootView 
                 attribute:NSLayoutAttributeCenterX 
                 multiplier:1.0 
                 constant:0.0]]; 
    [rootView addConstraint:[NSLayoutConstraint constraintWithItem:presentButton 
                 attribute:NSLayoutAttributeCenterY 
                 relatedBy:NSLayoutRelationEqual 
                  toItem:rootView 
                  attribute:NSLayoutAttributeCenterY 
                 multiplier:1.0 
                 constant:0.0]]; 
} 

- (void)present:(id)sender 
{ 
    BoardViewController *bvc = [[BoardViewController alloc] init]; 
    [self presentViewController:bvc animated:YES completion:NULL]; 
} 

Próbuję różnych reguł Układ automatyczny, ale bez względu na to, co robię, nie mogę dostać grę tablica do wypełnienia ekranu, gdy kontroler widoku jest prezentowany modalnie. (W tym samym czasie zadaję to pytanie, próbuję uzyskać środowisko wykonawcze, aby powiedzieć mi, co jego zdaniem jest niejednoznaczne, ale nie jestem jeszcze zbyt dobry w tym debugowaniu, stąd moje pytanie tutaj.)

Odpowiedz

2

Usuń:

mainView.translatesAutoresizingMaskIntoConstraints = NO;

to ciekawe, że to działa. Oznacza to, że gdy widok jest przedstawiony modally użyciu presentViewController oczekuje się mieć ograniczenia dotyczące go do SuperView, ale gdy ustawiony jako rootViewController z UIWindow ich nie potrzebują ...

+0

Genialny! Dziękuję Ci! Wyjaśnienie: źle zrozumiałem układ mojego widoku najwyższego poziomu, który jest przeglądem tego, kto mnie przedstawia. W tym przypadku 'presentViewController: animate: completion:' (zakładamy) dodaje swoje widoki za pomocą sprężyn-i-rozpór, więc je zepsułem. Czy to uczciwy sposób na stwierdzenie tego? –

+0

Z tego, co widzę, wynika, że ​​bycie 'rootViewController' okna jest specjalnym przypadkiem, który pomija więzy.Interesujące byłoby eksperymentowanie z tym, co by się stało, gdybyś wyszedł w 'mainView.translatesAutoresizingMaskIntoConstraints = NO;' i zaimplementował 'updateConstraints' aby ręcznie dodać pewne ograniczenia ... –

+0

Próbowałem zrzucić wartość' [self.view translatesAutoresizingMaskIntoConstraints] ' w 'viewDidAppear:' zarówno dla prezentacji modalnej, jak i kontrolera-set-as-root-view. W obu przypadkach wyrzucił TAK. Może ustawienie widoku jako kontroler widoku root jawnie ustawia jego ramkę, podczas gdy prezentowanie kontrolera widoku nie. –

2

Po pewnym dochodzenia, to wygląda podobnie jak po naciśnięciu pełnego kontrolera widoku modalnego i zakończeniu animacji, prezentujący kontroler widoku wraz z jego widokiem jest usuwany z hierarchii widoku. Zgodnie z oczekiwaniami, ograniczenia widoków są wówczas usuwane. Po zwolnieniu modalnego kontrolera widoku oryginalny viewcontroller z jego widokiem powraca ponownie, ale ograniczenia zostały usunięte i nie zostały zapisane i przywrócone przez system. To jest błąd. Nawet na iOS7. Powodem, dla którego działa funkcja NSAutoresizingConstraints, jest to, że system widoku jest w stanie samodzielnie odbudować wiązania.

Uwaga: jeśli masz konfigurację z zagnieżdżonymi kontrolerami viewControllers (np. Zewnętrzna kontrolka view osadza kontroler nawigacyjny), możesz połączyć je za pomocą wzorca potomnych kontrolek. Jeśli to zrobiłeś, najwyższy widok viewController jest usuwany przez to, co opisałem powyżej. Oznacza to, że musisz nanieść poprawkę NSAutoresizingConstraints tylko do tego najwyższego kontrolera view (zazwyczaj kontrolera viewer okna systemu Windows) i używać standardowych ograniczeń wszędzie tam, gdzie między nimi.

Powiązane problemy