NSGenericException',原因:'无法在视图上安装约束

时间:2013-02-12 12:54:44

标签: iphone objective-c ios6 xcode4.5

由于未捕获的异常'NSGenericException'

而终止应用程序
  

由于未捕获的异常'NSGenericException'而终止应用程序,原因:'无法在视图上安装约束。是约束   引用视图子树外的东西?那是   非法。约束:   视图:; layer =; contentOffset:{0,0}>'

7 个答案:

答案 0 :(得分:42)

您需要在两个视图的“更高”上安装约束。一个好的,通用的方法是这样的:

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

请注意:最好记住,约束属性是在添加它们的视图的上下文中进行评估的。因此,例如,对于viewB上安装的约束,viewA的NSLayoutAttributeLeft的值在viewB的坐标空间中进行解释。对于仅引用兄弟视图或其超级视图的约束,这个事实在很大程度上是无关紧要的,但是约束不能引用两个不是兄弟或直接父母的视图。

答案 1 :(得分:10)

与neoneye类似,由于删除了带有约束的子视图,我得到了这个。但是我有一个约束定位父视图,如果我调用了[self.view removeConstraints:self.view.constraints];,我就会删除它。相反,我做了这个更改,

原始代码:

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

已修复以删除子视图的约束:

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];
}

更新:所以我再次遇到此错误 - 这是因为此次删除了一个视图。添加了一个干净地删除视图的功能:

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];
}

答案 2 :(得分:3)

我在iOS6上遇到过这个错误。在我的情况下,这是因为我开始删除子视图而没有先删除约束。

// I had forgotten to remove constraints first. This caused the crash.
[self.view removeConstraints:self.view.constraints];

NSArray *subviews = self.view.subviews;
for (UIView *subview in subviews) {
    [subview removeFromSuperview];
}

[self addYourSubviewsHere];

答案 3 :(得分:2)

我使用类似UITextField的UIPickerView(使用Autolayout)来解决这个问题。当我推送另一个viewController并因此使用选择器将其弹出到viewController时,应用程序崩溃了。我在UIPickerViewController中找到了以下解决方案:

-(void)viewWillAppear:(BOOL)animated{

    [self.pickerView removeFromSuperview];
    [self.pickerView setTranslateAutoresizingMaskIntoContraints:YES];
    [self.view addSubview];

}   

从superview中删除后,您还可以设置UIPickerViewPosition。我希望能帮到你!

答案 4 :(得分:0)

我发现添加这一行代码修复了这个问题的可可ScrollView。

[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];

我认为某些视图会在运行时添加约束,因此当您添加自己的目标c时会发生冲突,因此您需要禁用此行为...

答案 5 :(得分:0)

同样的错误,不同的解决方案:

在添加新视图并忘记在界面构建器中关闭Use Auto Layout之后,我在iOS 6上启动我的应用时遇到此错误...我讨厌它没有标准设置 NOT 默认情况下为新视图使用自动布局...

答案 6 :(得分:0)

我遇到了同样的崩溃,结果是带有约束乘数值的浮点精度问题。我将所有约束乘数转换为漂亮的浮点值(例如0.375而不是0.35)并修复了崩溃。

AutoLayout: removeFromSuperview / removeConstraints throws exception and crashes hard