Dmytro N.
Dmytro N.

Reputation: 71

iOS Autolayout: Resizing container with constraints

I have a scroll view with container view(self.tagScrollContentView) inside. That's in Storyboard. Then I generate buttons and place them inside container view with constraints programmatically.

for(NSInteger i = 0; i < allTags.count; i++) {
   UIButton *tagBt = [[UIButton alloc] initWithFrame:(CGRect){CGPointZero, tagSize.width + 30, 17}];
   [self.tagScrollContentView addSubview:tagBt];

   [constraintsArray addObject:[NSLayoutConstraint constraintWithItem:tagBt attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:nil multiplier:1.0 constant:tagSize.width + 30]];

   if(prevBtRow1)
      [constraintsArray addObject:[NSLayoutConstraint constraintWithItem:tagBt attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:prevBtRow1 attribute:NSLayoutAttributeRight multiplier:1.0 constant:10.0]];
   else
      [constraintsArray addObject:[NSLayoutConstraint constraintWithItem:tagBt attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.tagScrollContentView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:10.0]];

   [constraintsArray addObject:[NSLayoutConstraint constraintWithItem:tagBt attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.tagScrollContentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:7.0]];

   prevBtRow1 = tagBt;
}

[self.tagScrollContentView addConstraints:constraintsArray];
[self.tagScrollView layoutSubviews];

This code put all buttons in a row depends of their width. All works fine. Then what I need is to enlarge tagScrollContentView to make all buttons become inside this view and not outside of bounds. Then to assign correct content size that is equal to container view to my scroll. Unfortunately scroll doesn't work correctly. Content size doesn't fit container view.

Upvotes: 2

Views: 2722

Answers (1)

Rob
Rob

Reputation: 437792

The key issue is that your contentSize is not getting set because you're not adding that final trailing constraint from the last button to its superview. You can add one more constraint at the end, and your contentSize will be adjusted automatically:

for (NSInteger i = 0; i < allTags.count; i++) {
    UIButton *tagBt = [[UIButton alloc] init];
    tagBt.translatesAutoresizingMaskIntoConstraints = NO;
    [self.tagScrollContentView addSubview:tagBt];

    // add all of your constraints

    prevBtRow1 = tagBt;
}

[constraintsArray addObject:[NSLayoutConstraint constraintWithItem:prevBtRow1
                                                         attribute:NSLayoutAttributeTrailing
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.tagScrollContentView
                                                         attribute:NSLayoutAttributeTrailing
                                                        multiplier:1.0
                                                          constant:10.0]];

[self.tagScrollContentView addConstraints:constraintsArray];

There are a couple of unrelated issues:

  1. I assume you had a tagBt.translatesAutoresizingMaskIntoConstraints = NO; line that didn't make it into your code sample.

  2. There's no point in doing initWithFrame if you're going to be setting constraints. init is sufficient.

  3. I'd suggest adding a height constraint to your button, too, so its constraints become unambiguous.

  4. By the way, you're adding the button width constraint to the superview. It works either way, but generally you add a constraint to the nearest common parent and for the width constraint, that would be the button itself, not its superview.

Upvotes: 1

Related Questions