2013-05-08 11 views
7

Próbuję wygenerować widok w kodzie. Oto hierarchię moim zdaniem obiektuUIScrollView z iOS Auto Layout Ograniczenia: Niewłaściwy rozmiar dla subviews

  • UIScrollView
    • UIView
      • UIButton

Scrollview powinien być taki sam rozmiar jak okna. Przycisk powinien być tak duży, jak to możliwe. używam iOS układ automatycznego, więc ciągi ograniczenie dla wszystkich moich obiektów wyglądać następująco

H:|[object]| 
V:|[object]| 

Ja również ustawić translatesAutoresizingMaskIntoConstraints do NO dla każdego obiektu.

Problem polega na tym, że przycisk przyjmuje tylko domyślny rozmiar przycisku. Jego obiekt widoku nadrzędnego (UIView) pobiera tylko rozmiar wymagany przez jego subviews.

enter image description here

czerwono: UIScrollView/żółty: UIView

Jak mogę zmusić te poglądy się być tak duży jak Scrollview?

Kiedy używam UIView zamiast th UIScrollView wszystko działa świetnie ...

Oto niektóre kodu:

- (void) viewDidLoad { 

     [super viewDidLoad]; 

     // SCROLL VIEW 
     UIScrollView* scrollView = [UIScrollView new]; 
     scrollView.backgroundColor=[UIColor redColor]; 
     scrollView.translatesAutoresizingMaskIntoConstraints = NO; 

     //CONTAINER VIEW 
     UIView *containerView = [UIView new]; 
     containerView.translatesAutoresizingMaskIntoConstraints = NO; 
     containerView.backgroundColor = [UIColor yellowColor]; 
     [scrollView addSubview:containerView]; 

     // CONSTRAINTS SCROLL VIEW - CONTAINER VIEW 
     [scrollView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView]|" 
               options:0 metrics:nil 
                views:@{@"containerView":containerView}]]; 
     [scrollView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView]|" 
               options:0 metrics:nil 
                views:@{@"containerView":containerView}]]; 

     // BUTTON 
     UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
     button.translatesAutoresizingMaskIntoConstraints = NO; 
     [button setTitle:@"I'm way to small" forState:UIControlStateNormal]; 
     [containerView addSubview:button]; 

     // CONSTRAINTS CONTAINER VIEW - BUTTON 
     [containerView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button]|" 
               options:0 metrics:nil 
                views:@{@"button":button}]]; 
     [containerView addConstraints: 
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button]|" 
               options:0 metrics:nil 
                views:@{@"button":button}]]; 
     self.view = scrollView; 

    } 

UPDATE: ja naprawdę nie wiem, dlaczego tak się dzieje . Jeśli ustawisz widok w IB, podłącz wyloty i zmodyfikuj widok w kodzie, przewijanie zachowuje się jak normalny widok (który odbija się pionowo). Jego contentSize nie jest obliczany poprawnie. Więcej here. Ale jak to zrobić poprawnie?

+0

To dość skomplikowane rozwiązanie, aby wyświetlić przycisk pełnoekranowy. Mam nadzieję, że odpowiedziałem na techniczne pytanie, ale wciąż nie jestem pewien, dlaczego robisz to w ten sposób. – Rob

+0

Proszę, przestańcie składać podziękowania w wiadomościach - podpisów tu nie ma. Dzięki! – Undo

Odpowiedz

23

Kilka uwag:

  1. Ograniczenia dla subviews w widokach przewijania nie działają jak ograniczenia w innych widokach. Służą do ustawiania widoku przewijania w postaci contentSize. (Zobacz TN2154.) W ten sposób rzucasz gromadą rzeczy w widoku przewijania, ustawiasz ograniczenia dla rzeczy wewnątrz niego, a contentSize jest obliczany dla ciebie. To bardzo fajna funkcja, ale jest to sprzeczne z tym, co próbujesz tutaj zrobić.

  2. Gorsze, przyciski będą, chyba że ustawisz wyraźne ograniczenie dla ich szerokości i wysokości przycisku, będą zmieniać rozmiar w zależności od ich zawartości.

Efekt netto tych dwóch obserwacji jest to, że istniejące ograniczenia powiedzieć „(a) ustawić mój zbiornik będzie rozmiar mojego przycisku; (b) niech mój przycisk zmiany rozmiaru się dynamicznie do rozmiaru tekstu oraz (c) ustaw mój scrollview na contentSize zgodnie z rozmiarem mojego kontenera (który jest wielkością przycisku). "

Nie mam pojęcia, czym jest problem biznesowy. Ale tutaj są pewne ograniczenia, które osiągają co myślę, że kwestia techniczna była:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIView *view = self.view; 

    UIScrollView *scrollView = [[UIScrollView alloc] init]; 
    scrollView.backgroundColor = [UIColor redColor]; // just so I can see it 
    scrollView.translatesAutoresizingMaskIntoConstraints = NO; 
    [self.view addSubview:scrollView]; 

    UIView *containerView = [[UIView alloc] init]; 
    containerView.backgroundColor = [UIColor yellowColor]; // just so I can see it 
    containerView.translatesAutoresizingMaskIntoConstraints = NO; 
    [scrollView addSubview:containerView]; 

    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    button.translatesAutoresizingMaskIntoConstraints = NO; 
    [button setTitle:@"I'm the right size" forState:UIControlStateNormal]; 
    [containerView addSubview:button]; 

    NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, button, view, containerView); 

    // set the scrollview to be the size of the root view 

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" 
                     options:0 
                     metrics:nil 
                     views:views]]; 

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" 
                     options:0 
                     metrics:nil 
                     views:views]]; 

    // set the container to the size of the main view, and simultaneously 
    // set the scrollview's contentSize to match the size of the container 

    [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView(==view)]|" 
                     options:0 
                     metrics:nil 
                     views:views]]; 

    [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView(==view)]|" 
                     options:0 
                     metrics:nil 
                     views:views]]; 

    // set the button size to be the size of the container view 

    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button(==containerView)]" 
                      options:0 
                      metrics:nil 
                      views:views]]; 

    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button(==containerView)]" 
                      options:0 
                      metrics:nil 
                      views:views]]; 

} 

Szczerze mówiąc, nie rozumiem intencję biznesowe swojego UI, jak to czuje się jak contortion w układ automatycznego osiągnąć bardzo prosto Interfejs użytkownika. Nie wiem, dlaczego masz widok przewijania, jeśli masz w nim zawartość "o rozmiarze ekranu" (chyba że korzystałeś z przycisków stronicowania). Nie wiem, dlaczego miałbyś widok treści z jednym elementem. Nie rozumiem, dlaczego używasz przycisku pełnoekranowego (po prostu w tym miejscu kliknęłbym gest w widoku głównym i nazwałbym go dzień).

Założę, że masz uzasadnione powody, ale może być sens tworzenia kopii zapasowych, zapytać, jakie są pożądane wrażenia użytkownika, a następnie podejść do problemu świeżo, aby sprawdzić, czy istnieje skuteczniejszy sposób osiągnąć pożądany efekt.

+0

"Nie rozumiem zamiaru biznesowego twojego interfejsu użytkownika ..." Próbuję automatycznie wygenerować dowolny interfejs na podstawie jego opisu. Przyciskiem w tym przykładzie może być dowolny zestaw subviews i ich subviews. W niektórych przypadkach opis mówi, że subview musi być tak szeroki jak superview (bez szerokości explizit). @Rob Dziękuję bardzo !!!!!! – Chrizzor

+0

Wysokość rozmiaru zawartości została już poprawnie obliczona w moim przykładzie, więc działało pionowe przewijanie. Szukałem contentSize w ten sposób: 'scrollView.contentSize = CGSizeMake (scrollView.frame.size.width,?)'. Aby to zrobić, usuń wszystkie wiązania pionowe z przykładu @Rob s: Przewijanie wciąż działa, a wszystkie widoki podrzędne mogą być tak szerokie, jak widok przewijania bez podania ich wyraźnej szerokości. – Chrizzor

Powiązane problemy