29

由于未捕获的异常“NSGenericException”而终止应用程序

由于未捕获的异常“NSGenericException”而终止应用程序,原因:“无法在视图上安装约束。约束是否引用了视图子树之外的内容?那是违法的。约束:视图:;层 = ; 内容偏移:{0, 0}>'

4

7 回答 7

53

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

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

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

于 2013-02-12T13:12:25.840 回答
11

与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];
}
于 2013-07-31T04:34:08.373 回答
4

我在 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];
于 2013-06-29T16:42:40.237 回答
2

我使用 UIPickerView 遇到了这个问题,比如 UITextField 的输入(使用 Autolayout)。当我推送另一个视图控制器并因此使用选择器将其弹出到视图控制器时,应用程序崩溃。我在 UIPickerViewController 中找到了以下解决方案:

-(void)viewWillAppear:(BOOL)animated{

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

}   

您还可以在从超级视图中删除后设置 UIPickerViewPosition。我希望这可以帮助你!

于 2014-01-24T18:45:50.253 回答
0

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

[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];

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

于 2014-01-18T01:09:39.570 回答
0

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

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

于 2014-04-04T08:44:28.740 回答
0

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

AutoLayout:removeFromSuperview / removeConstraints 抛出异常并严重崩溃

于 2017-04-21T12:44:13.603 回答