【问题标题】:NSGenericException', reason: 'Unable to install constraint on viewNSGenericException',原因:'无法在视图上安装约束
【发布时间】:2013-02-12 12:54:44
【问题描述】:

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

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

【问题讨论】:

  • 把代码放在这里了解更多
  • 您在哪个操作系统版本中收到此错误
  • 我怀疑您需要详细说明您的问题,和/或发布您的代码以获得更多有用的答案。

标签: iphone objective-c ios6 xcode4.5


【解决方案1】:

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

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

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

【讨论】:

  • 在我的应用程序中我使用日期选择器并在选择日期后导航到下一个视图,当我返回此视图控制器时应用程序崩溃并生成上述错误......
  • 这个ancestorSharedWithView 只为mac 定义而不是iOS?我看到它是在 AppKit.framework 库中定义的,它只属于 mac OSX10.8
  • 嗯。事实上,在 UIView 上似乎没有等价物,这似乎有点傻。编写这样的方法相当简单——只需沿着 firstView 的层次结构并在每一步询问[secondView isDescendantOfView: x]。但概念是一样的——你总是想在所有涉及的视图的共同祖先上安装一个约束,并且约束将在它安装的视图的坐标空间中解决。
【解决方案2】:

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

【讨论】:

    【解决方案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];
    

    【讨论】:

    • 这段代码的问题是它会删除 self.view 的所有约束,而不仅仅是与您要删除的子视图相关的约束...
    【解决方案4】:

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

    -(void)viewWillAppear:(BOOL)animated{
    
        [self.pickerView removeFromSuperview];
        [self.pickerView setTranslateAutoresizingMaskIntoContraints:YES];
        [self.view addSubview];
    
    }   
    

    您还可以在从 superview 中移除后设置 UIPickerViewPosition。希望对你有帮助!

    【讨论】:

    • 我有同样的问题,我使用UIDatePicker 作为TextFieldinputAccessoryView。我推了一个视图控制器然后回来,它抛出异常。我试过你的代码,但不适合我。请注意,我在情节提要中有UIDatePicker(不是通过代码创建的)。
    • 顺便说一下这个问题是一个iOS7的错误,我认为它会在7.1版本上得到修复。 iOS 在许多涉及自动布局的东西中都显示出很多问题。我也在故事板中使用pickerview,对我来说它有效。在让 viewController 之前,您可以尝试从 superview 中删除 datepicker。或者您可以尝试在 viewDidAppear 或 viewDidLayoutSubviews 上使用此代码。我希望它可以帮助你!谢谢你的报告。
    【解决方案5】:

    我发现添加这一行代码解决了可可滚动视图的这个问题。

    [scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
    

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        AutoLayout: removeFromSuperview / removeConstraints throws exception and crashes hard

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多