I am writing a custom view that is initialized programmatically. I override updateConstraints to add all the constraints needed for this view.
- (void)updateConstraints { [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTop multiplier:1 constant:0]]; [self.superview addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeBottom multiplier:1 constant:0]];
The problem is that self.bounds returns the equivalent of CGRectZero . I did my research and in accordance with this objc.io article , which is expected since the frame will not be set until layoutSubviews is called. It also mentions
To make the system update the layout of the view tree immediately, you can call layoutIfNeeded / layoutSubtreeIfNeeded (on iOS and OS X, respectively). This can be useful if your next steps rely on an updated frame.
However, when I add
[self setNeedsLayout]; [self layoutIfNeeded];
before setting self.bottomSpacingConstraint to updateConstraints , I still get CGRectZero back for the frame. According to the objc.io article (and this SO answer ), these methods should run the layout and update the frame.
Can anyone talk about how to make it all work? I am interested in the solution, as well as an explanation of the reasons why the methods associated with the layout are called (for example, it seems that changing the existing constraint constant in layoutSubviews causes a call to setNeedsUpdateConstraints , which then calls updateConstraints and causes the constraints to be added several times).
ios autolayout uiview
Scott Berrevoets
source share