UIScrollView with iOS Auto Layout Constraints: Wrong size for subviews

前端 未结 1 1175
旧时难觅i
旧时难觅i 2020-12-05 16:33

I\'m trying to generate a view in code. Here\'s the hierachy of my view object

  • UIScrollView
    • UIView
      • UIButton
相关标签:
1条回答
  • 2020-12-05 16:55

    A couple of observations:

    1. Constraints for subviews in scroll views don't work like constraints in other views. They're used to set the contentSize of the scroll view. (See TN2154.) That way, you throw a bunch of stuff on a scroll view, set the constraints for the stuff inside it, and the contentSize is calculated for you. It's very cool feature, but it's antithetical to what you're trying to do here.

    2. Worse, buttons will, unless you set an explicit constraint for their width and height of a button, will resize according to their content.

    The net effect of these two observations is that your existing constraints say "(a) set my container to be the size of my button; (b) let my button resize itself dynamically to the size of the text; and (c) set my scrollview's contentSize according to the size of my container (which is the size of the button)."

    I'm unclear as to what the business problem is. But here are some constraints that achieve what I think your technical question was:

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

    Frankly, I don't understand the business intent of your UI, as this feels like a contortion of auto layout to achieve a very simply UI. I don't know why you have a scroll view if you have "screen sized" content in it (unless you were paging through buttons). I don't know why you'd have a content view with a single item in it. I don't understand why you're using a full-screen button (I'd just put a tap gesture on the root view at that point and call it a day).

    I'll assume you have good reasons for all of this, but it might make sense to back up, ask what is your desired user experience is, and then approach the problem fresh to see if there's a more efficient way to achieve the desired effect.

    0 讨论(0)
提交回复
热议问题