Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSGenericException', reason: 'Unable to install constraint on view

Terminating app due to uncaught exception 'NSGenericException'

Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint: view:; layer = ; contentOffset: {0, 0}>'

like image 878
adevani11 Avatar asked Feb 12 '13 12:02

adevani11


Video Answer


2 Answers

You need to install the constraint on the "higher" of the two views. A good, general way to do this is like this:

NSLayoutConstraint* constraint = ...; NSView* firstView = constraint.firstItem; NSView* secondView = constraint.secondItem;     [[firstView ancestorSharedWithView: secondView] addConstraint: constraint]; 

Just a word of caution: It's good to remember here that constraint attributes are evaluated in the context of the view on which they are added. So for instance, the value of NSLayoutAttributeLeft of viewA, for a constraint installed on viewB, is interpreted in the coordinate space of viewB. For constraints that only reference sibling views or their superview, that fact is largely irrelevant, but there's no restriction that constraints can't reference two views that aren't siblings or direct parents.

like image 189
ipmcc Avatar answered Sep 21 '22 15:09

ipmcc


Similar to neoneye I was getting this due to removing subviews with constraints. However I had a constraint that was positioning the parent view, and this was being removed if I called [self.view removeConstraints:self.view.constraints]; Instead I made this change,

Original Code:

for (UIView *subview in [view subviews]) {     [subview removeFromSuperview]; } 

Fixed to remove constraints on subviews:

NSMutableArray * constraints_to_remove = [ @[] mutableCopy] ; for( NSLayoutConstraint * constraint in view.constraints) {     if( [view.subviews containsObject:constraint.firstItem] ||        [view.subviews containsObject:constraint.secondItem] ) {         [constraints_to_remove addObject:constraint];     } } [view removeConstraints:constraints_to_remove];  for (UIView *subview in [view subviews]) {     [subview removeFromSuperview]; } 

UPDATE: So I hit this error again - and it was due to removing a single view this time. Added a function to remove the view cleanly:

void cleanRemoveFromSuperview( UIView * view ) {   if(!view || !view.superview) return;    //First remove any constraints on the superview   NSMutableArray * constraints_to_remove = [NSMutableArray new];   UIView * superview = view.superview;    for( NSLayoutConstraint * constraint in superview.constraints) {     if( constraint.firstItem == view ||constraint.secondItem == view ) {       [constraints_to_remove addObject:constraint];     }   }   [superview removeConstraints:constraints_to_remove];    //Then remove the view itself.   [view removeFromSuperview]; } 
like image 40
Michael Anderson Avatar answered Sep 20 '22 15:09

Michael Anderson