web-dev-qa-db-fra.com

NSGenericException ', raison:' Impossible d'installer la contrainte sur l'affichage

Arrêt de l'application en raison d'une exception non interceptée 'NSGenericException'

Arrêt de l'application en raison d'une exception non interceptée 'NSGenericException', raison: 'Impossible d'installer la contrainte à la vue. Est-ce que la contrainte faire référence à quelque chose de l'extérieur du sous-arbre de la vue? C'est illégal. contrainte: vue:; couche =; contentOffset: {0, 0}> '

24
adevani11

Vous devez installer la contrainte sur la "plus haute" des deux vues. Voici une bonne façon générale de procéder: 

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

Juste un mot d'avertissement: il est bon de rappeler ici que les attributs de contrainte sont évalués dans le contexte de la vue sur laquelle ils sont ajoutés. Ainsi, par exemple, la valeur de NSLayoutAttributeLeft de viewA, pour une contrainte installée sur viewB, est interprétée dans l'espace de coordonnées de viewB. Pour les contraintes qui ne font que référencer les vues de frères ou soeurs ou leur super Vue d'ensemble, ce fait est en grande partie hors de propos, mais il n'y a aucune restriction indiquant que les contraintes ne peuvent pas faire référence à deux vues qui ne sont ni des frères ni des parents ni des parents directs.

41
ipmcc

Semblable à neoneye, je l’obtenais en raison de la suppression des sous-vues avec contraintes. Cependant, j'avais une contrainte qui positionnait la vue parente, et celle-ci était supprimée si j'appelais [self.view removeConstraints:self.view.constraints]; Au lieu de cela, j'ai apporté cette modification,

Code d'origine:

for (UIView *subview in [view subviews]) {
    [subview removeFromSuperview];
}

Correction pour supprimer les contraintes sur les sous-vues:

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: Donc, j'ai encore frappé cette erreur - et c'était en raison de la suppression d'une vue unique cette fois. Ajout d'une fonction pour supprimer la vue proprement:

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
Michael Anderson

J'ai rencontré cette erreur sur iOS6. Dans mon cas, c’est parce que j’ai commencé à supprimer les sous-vues sans d'abord supprimer les contraintes.

// 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];
3
neoneye

J'ai eu ce problème en utilisant un UIPickerView comme entrée d'un UITextField (en utilisant Autolayout). Lorsque j'appuie sur un autre viewController et qu'il apparaît ainsi dans viewController avec le sélecteur, l'application se bloque. J'ai trouvé la solution suivante dans UIPickerViewController:

-(void)viewWillAppear:(BOOL)animated{

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

}   

Vous pouvez également définir UIPickerViewPosition après la suppression de Superview. J'espère que cela peut vous aider!

2
Lucio Fonseca

Même erreur, solution différente ici:

J'ai eu cette erreur au démarrage de mon application sur iOS 6 après avoir ajouté une nouvelle vue et oublié de désactiver Use Auto Layout dans le générateur d'interface ... Je déteste qu'il n'y ait pas de réglage standard pour PAS utiliser la mise en page automatique par défaut pour les nouvelles vues ...

0
TheEye

J'ai eu le même crash, et il s'est avéré que c'était un problème de précision en virgule flottante avec des valeurs de multiplicateur de contrainte. J'ai converti tous mes multiplicateurs de contrainte en valeurs à virgule flottante de Nice (par exemple, 0,375 au lieu de 0,35), ce qui a résolu le problème.

AutoLayout: removeFromSuperview/removeConstraints lève une exception et se bloque brutalement

0
JimmyB

J'ai trouvé que l'ajout de cette ligne de code corrigeait ce problème pour un ScrollView au cacao.

[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];

Je pense que certaines vues ajoutent des contraintes au moment de l'exécution et sont donc conflictuelles lorsque vous ajoutez les vôtres via Objective C, vous devez donc désactiver ce comportement ...

0
David Douglas