Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autolayout seems not working when changing view dimensions programmatically

I have custom subclass of a UITableViewCell with some constraints set.

Problem is when I try to change size of one view like this:

CGRect frm = CGRectMake(0, 0, someValue, 30);
cell.indentView.frame = frm;

other views, which depend on cell.indentView width, are not moving at all.

What can be the case?

This code will work:

// enumerate over all constraints
for (NSLayoutConstraint *constraint in cell.indentView.constraints) {
    // find constraint on this view and with 'width' attribute
    if (constraint.firstItem == cell.indentView && constraint.firstAttribute == NSLayoutAttributeWidth)
    {
        // increase width of constraint
        constraint.constant = someValue;
        break;
    }
}
like image 558
Egor Avatar asked Jan 08 '13 13:01

Egor


2 Answers

It's because you cannot just change the frame of an object that has autolayout constraints (because constraints dictate the locations, not manually set frame properties ... the frame properties will be reset as constraints are reapplied). See this loosely related post in which it is demonstrated how to properly adjust a constraint to move a view. (In that case, we're animating, which is not the issue here, but it does demonstrate how how one adjusts a constraint to effect the movement of a UIView.)

In short, if you want to move a UIView within autolayout, you must not try to change the frame, but rather adjust the constraints themselves. This is simplified if you create IBOutlet references for the constraints themselves, at which point, you can adjust the constant of the NSLayoutConstraint.


Update:

Egor recommended enumerating the constraints and editing the one that matched the one in question. That works great, but personally, I prefer to have an IBOutlet for the specific constraint I want to edit rather than enumerating them and hunting the one in question. If you had an IBOutlet called indentViewWidthConstraint for the width NSLayoutConstraint of the indentView, you could then simply:

self.indentViewWidthConstraint.constant = newIndentConstantValue;
like image 138
Rob Avatar answered Nov 09 '22 17:11

Rob


You'll have to tell the framework to update e.g. by calling setNeedsLayout, setNeedsUpdateConstraints or layoutIfNeeded. See the documentation for UIView for the proper usage.

like image 30
SAE Avatar answered Nov 09 '22 15:11

SAE