0

I have the following situation:

  • UIScrollView ("_scrollView") with one child: UIView
  • UIView ("_layoutContainer") has a unknown number of childViews
  • childViews of UIView are added programmatically and their constraints are set programmatically.

Code for adding childviews (and my try to resize scrollview's content size):

- (void)viewDidLoad {
    [super viewDidLoad];
    UIView* lastLabel = _topCollectionView;
    for (int i = 0; i<50; i++) {
        UILabel* imageLabelView = [UILabel new];
        imageLabelView.translatesAutoresizingMaskIntoConstraints = NO;

        [_layoutContainer addSubview:imageLabelView];

        [_layoutContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[labelview]-(10)-|" options:0 metrics:nil views:@{@"labelview":imageLabelView}]];
        [_layoutContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousLabel]-(10)-[imagelabel(40)]" options:0 metrics:nil views:@{@"previousLabel":lastLabel, @"imagelabel":imageLabelView}]];

        imageLabelView.text = @"DUMMY";
        lastLabel = imageLabelView;
    }

    [_layoutContainer setNeedsLayout];
    [_layoutContainer layoutIfNeeded];
    _scrollView.contentSize = _layoutContainer.frame.size;
    [_scrollView invalidateIntrinsicContentSize];
}

My Storyboard Constraints look like this:

Constraints in Storyboard

This code works without any constraint errors in log and it looks like expected.

My problem is: The scrollview's content size doesn't change. I can add as many labels as I want to, but scrolling never works. Can you please help me to dynamically enlarge my scrollview?

1 Answer 1

1

If all the constraints makes a sufficient set to define an intrinsic content size in the container view, the scroll view -contentSize should resize accordingly, just need to call -(void)invalidateIntrinsicContentSize on the scroll view after you added the content.

- (void)viewDidLoad {
    [super viewDidLoad];
    UIView* lastLabel = _topCollectionView;
    for (int i = 0; i<50; i++) {
        UILabel* imageLabelView = [UILabel new];
        imageLabelView.translatesAutoresizingMaskIntoConstraints = NO;

        [_layoutContainer addSubview:imageLabelView];

        [_layoutContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[labelview]-(10)-|" options:0 metrics:nil views:@{@"labelview":imageLabelView}]];
        [_layoutContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousLabel]-(10)-[imagelabel(40)]" options:0 metrics:nil views:@{@"previousLabel":lastLabel, @"imagelabel":imageLabelView}]];

        imageLabelView.text = @"DUMMY";
        lastLabel = imageLabelView;
    }

    [_layoutContainer setNeedsLayout];
    [_layoutContainer layoutIfNeeded];
    [_scrollView invalidateIntrinsicContentSize];
    [_scrollView setNeedsLayout];
    [_scrollView layoutIfNeeded];
}
Sign up to request clarification or add additional context in comments.

4 Comments

Doesn't work. If I log the _layoutContainer size after adding all the view, i still get {{0, 0}, {1024, 768}} . I think the View inside the scrollView isn't updated. Will test some more..
Ok, try also that: do not call -layoutIfNeeded in the loop, after the loop say to the container view -setNeedsLayout and then -layoutIfNeeded. You should alway mark a view as in need of layout or the layout engine will skip it. I Updated the answer
Did it (and updated the code in my question). Unfortunately it did not change anything.
Got it! I had to add a bottom view constraint for the last label (after the loop): if (lastLabel) { [_layoutContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousLabel]-(10)-|" options:0 metrics:nil views:@{@"previousLabel":lastLabel}]]; } . Please edit your answer so I can accept it. Your if all the constraints makes a sufficient set (...) pointed me in the right direction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.