UIScrollView with iOS auto-layout restrictions: wrong size for prying

I am trying to create a view in code. Here is the hierarchy of the object of my view

  • UIScrollView
    • Uiview
      • UIButton

ScrollView must be the same size as the window. The button should be as large as possible. I use the automatic iOS layout, so the restriction lines for all my objects look like

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

I also set translatesAutoresizingMaskIntoConstraints to NO for each object.

The problem is that the button only gets the default size of the button. Its parent view object (UIView) gets only the size needed to view it.

enter image description here

red: UIScrollView / yellow: UIView

How can I make these views be as large as scrollView?

When I use UIView instead of UIScrollView everything works fine ...

Here is the 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: I really don't know why this is happening. If you configured the view in IB, plug in the outputs and initialize the view in code, scrollview behaves like a normal view (which bends vertically). Its contentSize is not computed correctly. More details here . But how to do it right?

+7
source share
1 answer

A few observations:

  • Restrictions for subviews in scroll views do not work as restrictions in other views. They are used to set the contentSize scroll. (See TN2154 .) Thus, you throw a bunch of things in the form of a scroll, set limits for the content inside it, and contentSize is designed for you. This is a very cool feature, but it contradicts what you are trying to do here.

  • Worse, the buttons will be, if you do not set an explicit restriction on their width and height, the buttons will resize according to their contents.

The net effect of these two observations is that your existing constraints say: "(a) set my container to the size of my button; (b) let my button dynamically resize dynamically to fit the text; (c) set my scrollview contentSize to match with the size of my container (which is the size of the button).

I do not understand what a business problem is. But here are some limitations that reach, in my opinion, your technical question:

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

Frankly, I donโ€™t understand the business purpose of your user interface, as it seems to distort the automatic layout to achieve a very simple interface. I donโ€™t know why you have scrolling if you have a โ€œscreen sizeโ€ in it (unless you looked at the buttons through the buttons). I do not know why you will have a presentation of content with one element in it. I donโ€™t understand why you are using the full-screen button (I would just place a tap in the root view at that moment with a gesture and call it day).

I assume that you have good reasons for all this, but it might make sense to back up, ask what your desired user experience is, and then approach the problem to find out if there is a more effective way to achieve the desired effect.

+23
source

All Articles