29

キャッチされなかった例外「NSGenericException」が原因でアプリを終了しています

キャッチされなかった例外'NSGenericException'が原因でアプリを終了しています。理由:'ビューに制約をインストールできません。制約は、ビューのサブツリーの外側から何かを参照していますか?それは違法です。制約:ビュー:; レイヤー=; contentOffset:{0、0}> '

4

7 に答える 7

53

2 つのビューの「高い」側に制約をインストールする必要があります。これを行うための適切で一般的な方法は次のとおりです。

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

注意点: 制約属性は、それらが追加されたビューのコンテキストで評価されることを覚えておくとよいでしょう。たとえば、viewA の NSLayoutAttributeLeft の値は、viewB にインストールされた制約に対して、viewB の座標空間で解釈されます。兄弟ビューまたはそのスーパービューのみを参照する制約の場合、その事実はほとんど関係ありませんが、制約が兄弟または直接の親ではない 2 つのビューを参照できないという制限はありません。

于 2013-02-12T13:12:25.840 に答える
11

neoeye と同様に、制約のあるサブビューを削除したためにこれを取得していました。ただし、親ビューを配置する制約があり、これを呼び出すと削除されていましたが、[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

UITextFieldの入力のようなUIPickerViewを使用して(Autolayoutを使用して)この問題が発生しました。別のviewControllerをプッシュして、ピッカーでviewControllerにポップすると、アプリがクラッシュします。UIPickerViewController で次の解決策を見つけました。

-(void)viewWillAppear:(BOOL)animated{

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

}   

スーパービューから削除した後、UIPickerViewPosition を設定することもできます。それがあなたを助けることができることを願っています!

于 2014-01-24T18:45:50.253 に答える
0

同じエラー、別の解決策:

Use Auto Layout新しいビューを追加した後、iOS 6 でアプリを起動し、インターフェイス ビルダーでそれをオフにするのを忘れたときにこのエラーが発生しました...新しいビューに対してデフォルトで自動レイアウトを使用しない標準設定がないのが嫌いです.. .

于 2014-04-04T08:44:28.740 に答える