web-dev-qa-db-fra.com

ajouter des contraintes par programme swift

J'essaie d'ajouter des contraintes à un bouton de connexion facebook sdk.

J'ai le bouton dans une vue de défilement et j'essaie d'ajouter une contrainte supérieure à une étiquette qui se trouve également dans la vue de défilement. Je suis en mesure d'ajouter avec succès la contrainte de hauteur sans erreur d'exécution, mais la contrainte réelle ne semble pas être appliquée au bouton.

@IBOutlet weak var orLbl: UILabel!
@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()
    var loginFBButton = FBSDKLoginButton()
    loginFBButton.readPermissions = ["public_profile", "email"]

    let heightConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Height,
        relatedBy: NSLayoutRelation.Equal,
        toItem: nil,
        attribute: NSLayoutAttribute.NotAnAttribute,
        multiplier: 1,
        constant: 41)
    let topConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.TopMargin,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.orLbl,
        attribute: NSLayoutAttribute.BottomMargin,
        multiplier: 1,
        constant: 31)
    let leadingConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.registerButton,
        attribute: NSLayoutAttribute.Left,
        multiplier: 1,
        constant: 0)
    let trailingConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.registerButton,
        attribute: NSLayoutAttribute.Right,
        multiplier: 1,
        constant: 0)

    self.scrollView.addSubview(loginFBButton)
    //loginFBButton.center = self.scrollView.center

    loginFBButton.addConstraints([heightConstraint, topConstraint])

}

Ensuite, lorsque j'inclus l'ajout de la contrainte supérieure, j'obtiens une erreur d'exécution:

Lorsqu'ils sont ajoutés à une vue, les éléments de la contrainte doivent être des descendants de cette vue (ou de la vue elle-même). Cela se bloquera si la contrainte doit être résolue avant l'assemblage de la hiérarchie de vues.

Arrêt de l'application en raison d'une exception non interceptée "NSGenericException", raison: "Impossible d'installer la contrainte sur la vue. La contrainte fait-elle référence à quelque chose de l'extérieur du sous-arbre de la vue? C'est illégal.

L'étiquette et le bouton facebook sont tous deux dans ma vue de défilement? J'ai même imprimé orLbl.superview et loginFBButton.superview et je reçois uiscrollview en option pour les deux

13
user2363025

Il existe un nouveau (iOS8, OS 10.10), un moyen plus simple d'activer les contraintes qui n'implique pas de déterminer à quelles vues les ajouter. Les contraintes savent déjà à quelles vues elles appartiennent, alors assurez-vous d'abord que vos vues ont été ajoutées en tant que sous-vues, puis appelez la méthode de classe activateConstraints sur NSLayoutConstraint pour les activer:

 NSLayoutConstraint.activateConstraints([heightConstraint, topConstraint])

Lorsque vous créez des éléments d'interface utilisateur par programme, vous devez dire à iOS de ne pas transformer son cadre en contraintes. Pour ce faire, juste après avoir créé loginFBButton faites:

Pour Swift 1.2:

loginFBButton.setTranslatesAutoresizingMaskIntoConstraints(false)

Pour Swift 2.0 & 3.0:

loginFBButton.translatesAutoresizingMaskIntoConstraints = false

Enfin, vous allez avoir besoin de plus de contraintes. Je suggère de définir une contrainte de largeur pour votre loginFBButton et d'ajouter une contrainte pour positionner le bouton horizontalement.

29
vacawama