12

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;
    }
}
Egor
  • 423
  • 1
  • 4
  • 13
  • 3
    AutoLayout is so ugly, it made me cry. Happy Coding! – MCKapur Jan 08 '13 at 13:28
  • 1
    +1 to above autolayout haters. That's the worst of hell. You need to think a hundred times before using it in a project harder than trivial. I'd better add a few lines of code calculating frames on some screens. – dreamzor Jan 08 '13 at 13:37
  • @Rob And the worst part, it just feels like turning on itself even when you set the deployment target to >= iOS 5! – MCKapur Jan 08 '13 at 13:42

2 Answers2

13

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;
Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044
2

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.

SAE
  • 1,609
  • 2
  • 18
  • 22
  • This wasn't enough for me - had to change the constraint as per the question and the other answer. – Bryan Jan 29 '15 at 10:02