J'essaie de créer une vue qui agira comme une sorte de "panneau", attachée au côté droit du contrôleur de vue.
Autrement dit, il est lié aux marges de fin, supérieure et inférieure du contrôleur de vue parent, avec une largeur statique de 300.
Cependant, je n'arrive tout simplement pas à comprendre, je suis en train de casser une contrainte ou de faire quelque chose que xcode dit illégal.
Qu'est-ce que je fais mal?
Voici le code dans le contrôleur
let myView = UIView()
view.backgroundColor = UIColor.redColor()
self.view.addSubview(view)
let topConstraint = NSLayoutConstraint(item: myView,
attribute: .Top,
relatedBy: .Equal,
toItem: self.topLayoutGuide,
attribute: .Bottom,
multiplier: 1,
constant: 0)
let trailingConstraint = NSLayoutConstraint(item: self.view,
attribute: .TrailingMargin,
relatedBy: .Equal,
toItem: myView,
attribute: .Trailing,
multiplier: 1,
constant: 0)
let bottomConstraint = NSLayoutConstraint(item: self.bottomLayoutGuide,
attribute: .Top,
relatedBy: .Equal,
toItem: myView,
attribute: .Bottom,
multiplier: 1,
constant: 0)
let widthConstraint = NSLayoutConstraint(item: myView,
attribute: .Width,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1,
constant: 300)
self.view.addConstraints([trailingConstraint])
view.addConstraints([topConstraint, bottomConstraint, widthConstraint])
En réalité, le problème dans votre code est que vous n'avez pas défini la variable translatesAutoresizingMaskIntoConstraints
de myview
sur false
, chaque fois que vous souhaitez utiliser des contraintes de présentation automatique, vous devez définir la variable translatesAutoresizingMaskIntoConstraints
d'une vue sur false ..__ ajoutez myview
sur self.view J'ai mis à jour votre code et il fonctionne parfaitement en fonction de vos contraintes.
Mettez le code ci-dessous dans votre ViewController.
let myView = UIView()
myView.backgroundColor = UIColor.redColor()
self.view.addSubview(myView)
myView.translatesAutoresizingMaskIntoConstraints = false
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Bottom, relatedBy: .Equal, toItem: self.bottomLayoutGuide, attribute:.Top, multiplier: 1, constant: 20))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 300))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .TrailingMargin, relatedBy: .Equal, toItem: view, attribute: .TrailingMargin, multiplier: 1, constant: 0))
Dans votre exemple de code ci-dessus, il semble que vous mélangez view
et myView
à quelques endroits. Quoi qu'il en soit, widthConstraint
doit être ajouté à myView
et topConstraint
, trailingConstraint
et bottomConstraint
doivent être ajoutés à self.view
. La raison en est que des contraintes doivent être ajoutées à l'ancêtre superview le plus proche, qui expose les deux vues impliquées dans la contrainte. Dans le cas où vous contraignez un attribut de vue enfant à un attribut de sa vue parent, la contrainte doit être ajoutée à la vue parent, car elle présente à la fois elle-même et la vue enfant. Si vous avez une contrainte entre deux vues jumelles, elle sera ajoutée à la vue parent car c'est l'ancêtre le plus proche qui affiche les deux vues impliquées.
Si vous êtes en mesure de cibler iOS 9.0 et les versions ultérieures, il est beaucoup plus simple et plus propre d'utiliser les nouveaux API NSLayoutAnchor et NSLayoutDimension pour créer ce type de contraintes. Il fournit également une vérification de type stricte et le compilateur peut vérifier son exactitude. Avec ces nouvelles API, votre exemple de code deviendrait simplement:
let myView = UIView()
myView.backgroundColor = UIColor.redColor()
self.view.addSubview(myView)
let margins = self.view.layoutMarginsGuide
myView.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor).active = true
myView.topAnchor.constraintEqualToAnchor(margins.topAnchor).active = true
myView.bottomAnchor.constraintEqualToAnchor(margins.bottomAnchor).active = true
myView.widthAnchor.constraintEqualToConstant(300.0).active = true
Il n'est pas nécessaire d'ajouter explicitement les contraintes à la vue de droite, etc. Vous pouvez en savoir plus sur cette méthode de création de contraintes ici:
et ici:
Il semble y avoir une certaine ambiguïté dans votre code, vous créez une UIView en tant que myView mais ajoutez view à self.view et même une contrainte pour s’afficher. Donc corrigez votre code et remplacez view par myView . Deuxièmement, setTranslayesAutoresizingMaskIntoConstraints to false . Ajoutez ensuite toutes les contraintes à self.view. Cela devrait résoudre votre problème.
myView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addConstraints([trailingConstraint, bottomConstraint, widthConstraint])
VFL est également une approche meilleure et propre. Cela donne en fait une visualisation de la configuration des contraintes.