131

The question I have is simple but I couldn't find any information in the documentation.

What happens with layout constraints when a view is removed from the view hierarchy (or moved to another view)?

For example, let's have container C with subviews A and B. Container C holds some constraints. Then we call [A removeFromSuperview]. What happens with the constraints for A?

What then happens if we add A to C again?

Sulthan
  • 128,090
  • 22
  • 218
  • 270

6 Answers6

130

The constraints are removed. If you add A again, you will have to make new constraints for it, or if you save the constraints before you remove A, you can add them back. When I do something like this, I save the constraints like this for a view called view1:

self.portraitConstraints = [NSMutableArray new];
for (NSLayoutConstraint *con in self.view.constraints) {
    if (con.firstItem == self.view1 || con.secondItem == self.view1) {
       [self.portraitConstraints addObject:con];
    }
}
rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • 7
    Can be this fact found somewhere in the documentation? I believe you but it seems strange the fact isn't mentioned anywhere. – Sulthan Sep 04 '13 at 15:53
  • 2
    It's common sense that the constraints are removed along with the view really. If they weren't how would the layout system be able to evaluate them in a future pass? – Mike Pollard Sep 04 '13 at 16:13
  • 6
    For as obvious as this answer seems like it would be, it was still tremendously helpful! – race_carr Mar 21 '14 at 17:46
  • 1
    @pnollet, I don't know why the poster in that question did what he did. I've logged this to verify, and when I remove a subview, and check the constraints on the superview, those constraints that pertained to the removed subview are gone. – rdelmar Apr 22 '14 at 15:18
  • @MikePollard while I'm sure it's common sense, in your experience, how often does common sense *actually* effect anything regarding programming? (Though what's actually going on is that there are complications that you overlook that then make 'common sense' stand on it's head... :D ) – RonLugge May 14 '14 at 22:18
  • I would like a doc reference for this. I do not think your claim is always the case. I just ran into a situation where constraints were being retained even after a view had been removed from its super view and set to nil. It was only happening on iOS 6.1 though, not 7.1. I could literally log the difference just by running on different devices. – Firo Aug 25 '14 at 19:56
  • @Firo, I don't know a doc reference for this, but as Mike Pollard said in his comment, it only makes sense. Did you get an error in iOS 6 after removing the view (since the constraints you say are retained would be referencing a view no longer in the hierarchy, you should get a crash)? – rdelmar Aug 25 '14 at 20:46
  • Yes, the application crashed and said that it was attempting to fulfill a constraint for a view no longer in the view hierarchy. I had to manually go through and remove the constraints. I agree that it is common sense for them to be removed. However, as RonLugge pointed out, common sense is not always the rule. – Firo Aug 25 '14 at 21:21
  • 4
    @Firo, I'm sure they're supposed to be removed, so if they're not in iOS 6, it's probably a bug. BTW, the doc for the removeFromSuperview method says, "Calling this method removes any constraints that refer to the view you are removing, or that refer to any view in the subtree of the view you are removing". – rdelmar Aug 25 '14 at 22:42
  • Ah, very nice! Yes, I see that now. I would probably include that in your answer, it is more concrete than an example or assumption. It must be a bug then. Thanks! – Firo Aug 26 '14 at 12:58
  • I tried to get constraints of my UITableView, but I am getting "0 Elements." Could anybody please explain the reason behind this ? PS - I Have added constraints in my storyboard and trying to get them in my Class – Ashutosh Shukla Jan 09 '20 at 07:23
50

Since I had this question too, I checked the Apple Docs just for kicks, and it turns out that it is documented that the constraints are removed.

The documentation for the UIView removeFromSuperview method states:

Calling this method removes any constraints that refer to the view you are removing, or that refer to any view in the subtree of the view you are removing.

I'm not sure if this was documented last year when the original question was posted, but I just thought I'd share this information in case anyone needed it...

Evan K. Stone
  • 1,169
  • 11
  • 15
3

Be aware though, that if you have two independent parent views A and B, and a subview C, where C is currently a subview of A, with appropriate constraints, that calling [B addSubview:C] will NOT clear any constraints relating to A and C, and auto layout will start throwing exceptions, because those constraints no longer relate to views in the same hierarchy.

You will need to call [C removeFromSuperview] explicitly to remove the constraints, before adding C to B.

This is true on Mac OS X - I haven't checked iOS

  • Interesting! Where did you get this information? The docs for addSubview don't mention this behaviour. I'm asking because I currently have a sporadic exception, when removing a view controller, that states 'Unable to install constraint on view' -- something I'm not doing. – JimmyB Apr 20 '17 at 14:38
2

The constraints are also removed when you [A removeFromSuperview]

They are forgotten and adding A to C again adds no constraints.

Mike Pollard
  • 10,195
  • 2
  • 37
  • 46
0

They are removed too, you can do a simple test. Pick up a view SUBVIEW and create costraints that constraint SUBVIEW to follow its superview resizing (like attched to to superview edges). To do that you add SUBVIEW as a subview to this CONTAINERVIEW and add as constraints something like that:
V:|-[SUBVIEW]-|
H:|-[SUBVIEW]-|
These constraints should be added to SUBVIEW superview, thus CONTAINERVIEW.
If you remove SUBVIEW by simply checking all the CONTAINERVIEW constraints you could see that two aren't around anymore.

Andrea
  • 26,120
  • 10
  • 85
  • 131
-1

This question also can be proved by interface builder. When drag and drop a UIView on the ViewController add constraints then remove the UIView, you can see the blue constraints disappear.

William Hu
  • 15,423
  • 11
  • 100
  • 121
  • 6
    Storyboard proves nothing about how runtime behavior will occur. Storyboard can do whatever it wants! – mxcl Sep 24 '17 at 16:42