2013-05-08 6 views
7

Ich versuche, eine Ansicht in Code zu generieren. Hier ist die Hierachie meiner Ansicht ObjektUIScrollView mit iOS Auto Layout Einschränkungen: Falsche Größe für Subviews

  • UIScrollView
    • UIView
      • UIButton

Die Scroll sollte die gleiche Größe wie die Fenster sein. Der Knopf sollte so groß wie möglich sein. Ich bin mit iOS Auto-Layout, so dass die Constraint-Strings für alle meine Objekte sehen aus wie dieses

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

ich auch translatesAutoresizingMaskIntoConstraints-NO für jedes Objekt festgelegt haben.

Das Problem ist, dass die Schaltfläche nur die Standardgröße der Schaltfläche erhält. Das übergeordnete Ansichtsobjekt (UIView) erhält nur die Größe, die seine Teilansichten benötigen.

enter image description here

rot: UIScrollView/gelb: UIView

Wie kann ich zwingen, diese Ansichten so groß wie die Scrollview zu sein?

Wenn ich eine UIView statt verwenden th UIScrollView alles funktioniert super ...

Hier einige Code:

- (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: Ich weiß nicht wirklich, warum dies geschieht . Wenn Sie die Ansicht in IB einrichten, die Ausgänge verbinden und die Ansicht in Code instanziieren, verhält sich die Bildlaufansicht wie eine normale Ansicht (die vertikal springt). Seine contentSize wird nicht korrekt berechnet. Mehr here. Aber wie macht man das richtig?

+0

Dies ist eine ziemlich komplizierte Lösung, nur um eine Vollbild-Schaltfläche anzuzeigen. Hoffentlich habe ich die technische Frage beantwortet, aber ich weiß immer noch nicht, warum du es so machst. – Rob

+0

Bitte hör auf deinen Dank in Beiträge - Signaturen gehören nicht hierher. Vielen Dank! – Undo

Antwort

23

Ein paar Beobachtungen:

  1. Einschränkungen für Subviews in Scroll-Ansichten wie Einschränkungen nicht in anderen Ansichten arbeiten. Sie werden verwendet, um die contentSize der Bildlaufansicht festzulegen. (Siehe TN2154.) Auf diese Weise werfen Sie eine Menge Dinge auf eine Bildlaufansicht, legen die Einschränkungen für das darin enthaltene Material fest und der Wert contentSize wird für Sie berechnet. Es ist eine sehr coole Funktion, aber es steht im Gegensatz zu dem, was Sie hier versuchen.

  2. Schlimmer noch, werden Schaltflächen, sofern Sie nicht eine explizite Einschränkung für ihre Breite und Höhe einer Schaltfläche festlegen, wird die Größe entsprechend ihrem Inhalt.

Der Nettoeffekt dieser beiden Beobachtungen ist, dass Ihre bestehenden Einschränkungen „sagen (a) gesetzt meinen Behälter die Größe meiner Taste sein, (b) lassen meine Taste selbst auf die Größe des Textes dynamisch die Größe ; und (c) setze die Scrollview contentSize entsprechend der Größe meines Containers (was die Größe der Schaltfläche ist). "

Ich bin unklar, was das Geschäftsproblem ist. Aber hier sind einige Einschränkungen, die das erreichen, was ich denke, Ihre technische Frage war:

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

} 

Ehrlich gesagt, ich habe nicht die Absicht, Unternehmen der Benutzeroberfläche verstehen, wie dies wie eine Verrenkung des Auto-Layout fühlt sich ein zu erreichen, sehr einfach Benutzeroberfläche. Ich weiß nicht, warum Sie eine Bildlaufansicht haben, wenn Sie Inhalte in Bildschirmgröße haben (es sei denn, Sie blättern durch die Schaltflächen). Ich weiß nicht, warum Sie eine Inhaltsansicht mit einem einzelnen Element haben. Ich verstehe nicht, warum du eine Vollbild-Schaltfläche verwendest (ich würde einfach eine Tippgeste auf die Grundansicht setzen und es dann zu einem Tag machen).

Ich nehme an, Sie haben gute Gründe für all dies, aber es könnte sinnvoll sein, zu sichern, fragen, was ist Ihre gewünschte Benutzererfahrung ist, und dann das Problem frisch anzugehen, um zu sehen, ob es einen effizienteren Weg ist den gewünschten Effekt erzielen.

+0

"Ich verstehe den Geschäftszweck Ihrer UI nicht ..." Ich versuche, basierend auf der Beschreibung automatisch jede Benutzeroberfläche zu generieren. Die Schaltfläche im Beispiel könnte eine beliebige Gruppe von Unteransichten und deren Unteransichten sein. In einigen Fällen sagt die Beschreibung, dass eine Unteransicht so breit sein muss wie die Superansicht (keine explizite Breite). @Rob Vielen Dank !!!!!! – Chrizzor

+0

Die Höhe der Inhaltsgröße wurde in meinem Beispiel bereits korrekt berechnet, sodass das vertikale Scrollen funktionierte. Ich suchte nach einer contentSize wie folgt: 'scrollView.contentSize = CGSizeMake (scrollView.frame.size.width,?)'. Entfernen Sie dazu alle vertikalen Abhängigkeiten aus @Robs Beispiel: Das Scrollen funktioniert noch immer und alle Untersichten können so breit wie die Bildlaufansicht sein, ohne dass ihnen eine explizite Breite zugewiesen wird. – Chrizzor