web-dev-qa-db-fra.com

Pourquoi faible IBOutlet NSLayoutConstraint passe à zéro quand je le fais inactif?

J'ai un IBOutlet NSLayoutConstraint dans mon application. Très simple:

@property (nonatomic, weak) IBOutlet NSLayoutConstraint* leftConstraint;

À un moment donné, je souhaite désactiver cette contrainte:

self.leftConstraint.active = NO;

Cela se produit dans une méthode appelée depuis cellForRowAtIndexPath:. Et la contrainte devient nulle juste après la ligne ci-dessus. Cependant, si je déclare cette propriété en tant que strong, tout va bien, elle ne devient pas nil. Quelqu'un peut-il expliquer pourquoi cela se produit?

18
Andrey Chernukha

Lorsque votre sortie est weak, la seule référence strong provient de la propriété constraints de la vue. La désactivation de la contrainte la supprime de ce tableau, de sorte qu'il n'y a plus de références fortes.

48
Avi

Une solution de contournement possible consisterait à modifier la priorité de la contrainte au lieu de la rendre inactive:

@property (nonatomic, weak) IBOutlet NSLayoutConstraint* leftConstraint;
(...)
self.leftConstraint.priority = 250;

Ensuite, self.leftConstraint n'est pas éliminé.

MODIFIER:

Xcode ne prend pas en charge le changement de priorité pour les contraintes requises (= 1000), assurez-vous donc que vous basculez dans une plage comprise entre 1 ... 999. 

5
Fran Pugl

Commencez par modifier la variable IBOutlet en option. c'est à dire:

de :

@IBOutlet weak var myConstraint : NSLayoutConstraint!

à:

@IBOutlet weak var myConstraint : NSLayoutConstraint?

Maintenant, pour faciliter la gestion/modification du storyboard à l'avenir, ajoutez une nouvelle variable (par exemple, myConstraint_DefualtValue ) et définissez-la sur la valeur de myConstraint in viewDidLoad

var myConstraint_DefualtValue = CGFloat(0)
override func viewDidLoad() {
    super.viewDidLoad()

    self.myConstraint_DefualtValue = self.myConstraint.constant

}

Je suppose qu'il est évident que vous devez le définir dans viewDidLoad et pas ailleurs

Ensuite, lorsque vous souhaitez le désactiver:

self.myConstraint?.isActive = false

Et lorsque vous souhaitez le réactiver (en supposant que vous avez la vue comme sortie ( myViewThatHasTheConstraint ) et que la contrainte est une hauteur contrainte):

self.myConstraint = self.myViewThatHasTheConstraint.heightAnchor.constraint(equalToConstant: self.myConstraint_DefualtValue);
self.myConstraint?.isActive = true
1
Mjd Mz