web-dev-qa-db-ja.com

NSGenericException '、理由:'ビューに制約をインストールできません

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

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

27
adevani11

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

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

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

44
ipmcc

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

[〜#〜] update [〜#〜]:ですから、このエラーに再度遭遇しました-今回は単一のビューを削除したことが原因でした。ビューをきれいに削除する関数を追加しました:

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

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];
4
neoneye

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

-(void)viewWillAppear:(BOOL)animated{

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

}   

スーパービューから削除した後にUIPickerViewPositionを設定することもできます。お役に立てれば幸いです。

2
Lucio Fonseca

同じエラー、ここでの異なる解決策:

新しいビューを追加し、スイッチを切るのを忘れた後、iOS 6でアプリを起動すると、このエラーが発生しましたUse Auto Layoutインターフェースビルダーでオン...標準設定はありません[〜#〜] not [〜#〜]新しいビューにデフォルトで自動レイアウトを使用...

0
TheEye

同じクラッシュが発生しましたが、制約の乗数の値に関する浮動小数点の精度の問題であることが判明しました。すべての制約乗数をニース浮動小数点値(0.35ではなく0.375など)に変換し、クラッシュを修正しました。

AutoLayout:removeFromSuperview/removeConstraintsが例外をスローし、ハードクラッシュします

0
JimmyB

この1行のコードを追加すると、cocoa ScrollViewのこの問題が修正されました。

[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];

特定のビューは実行時に制約を追加するため、Objective Cを介して独自のビューを追加すると競合するため、この動作を無効にする必要があると思います...

0
David Douglas