NSGenericException ', причина:' Невозможно установить ограничение на просмотр

Завершение приложения из-за неотображенного исключения "NSGenericException"

Завершение приложения из-за неперехваченного исключения "NSGenericException", причина: "Невозможно установить ограничение на просмотр. Имеет ли ограничение ссылку что-то извне поддерева зрения? Это незаконным. ограничение: Посмотреть:; layer =; contentOffset: {0, 0} > '

Ответ 1

Вам нужно установить ограничение на "высшее" из двух представлений. Хороший, общий способ сделать это выглядит следующим образом:

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

Просто предостережение: хорошо помнить, что атрибуты ограничений оцениваются в контексте представления, на котором они добавлены. Так, например, значение NSLayoutAttributeLeft для viewA для ограничения, установленного на viewB, интерпретируется в координатном пространстве viewB. Для ограничений, которые ссылаются только на представления собора или их надзора, этот факт в значительной степени не имеет значения, но нет ограничений, которые ограничения не могут ссылаться на два представления, которые не являются братьями и сестрами или прямыми родителями.

Ответ 2

Подобно neoneye, я получал это из-за удаления subviews с ограничениями. Однако у меня было ограничение, которое позиционировало родительское представление, и это удалялось, если я вызывал [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];
}

Ответ 3

Я испытал эту ошибку на iOS6. В моем случае это было связано с тем, что я начал удалять subviews без предварительного удаления ограничений.

// 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

У меня возникла проблема с использованием UIPickerView, например, ввода UITextField (с использованием Autolayout). Когда я нажимаю другой viewController и, таким образом, выворачиваю его в viewController с помощью сборщика, приложение падает. Я нашел следующее решение в UIPickerViewController:

-(void)viewWillAppear:(BOOL)animated{

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

}   

Вы также можете установить UIPickerViewPosition после удаления из супервизора. Надеюсь, это поможет вам!

Ответ 5

Я обнаружил, что добавление этой строки кода исправляет эту проблему для cocoa ScrollView.

[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];

Я думаю, что некоторые представления добавляют ограничения во время выполнения, поэтому конфликтуют, когда вы добавляете свой собственный через цель c, поэтому вам нужно отключить это поведение...

Ответ 6

Такая же ошибка, другое решение здесь:

Я получил эту ошибку при запуске моего приложения на iOS 6 после добавления нового представления и забыл отключить Use Auto Layout на нем в построителе интерфейса... Я ненавижу, что нет стандартных настроек для НЕ использовать автоматический макет по умолчанию для новых просмотров...

Ответ 7

У меня был такой же сбой, и он оказался проблемой точности с плавающей запятой с значениями множителя ограничения. Я преобразовал все мои множители ограничения в хорошие значения с плавающей запятой (например, 0,375 вместо 0,35), и это зафиксировало сбой.

AutoLayout: removeFromSuperview/removeConstraints выдает исключение и сильно сработает