2017-04-04 2 views
2

Ci-dessous, j'ai inclus du code pour votre paiement. J'essaie de prendre un UIView personnalisé et d'ajouter une autre sous-vue personnalisée. Cette sous-vue doit être contrainte à la vue parente de telle sorte qu'elle repose essentiellement sur les mêmes dimensions et que le parent agit comme un wrapper.Définition automatique des contraintes de mise en page automatique pour les sous-vues d'un UIView

J'ai essayé d'utiliser le NSLayoutConstraint et ai échoué misérable jusqu'à présent. La vue n'apparaît jamais réellement. J'ai une contrainte gauche, droite, inférieure et supérieure qui devrait s'aligner avec la vue parent.

La première question que j'ai, c'est que quelqu'un explique et corrige ma logique en utilisant la méthode suivante. L'élément param que j'ai figuré est la vue réelle pour laquelle vous voulez définir une contrainte pour (customViewChild). L'attribut est de dire que je veux que le bord gauche de mon customViewChild soit utilisé pour cette contrainte. Le relatedBy semble assez simple bien que je puisse me tromper, et finalement le toItem points à moi qui est mon qui a aussi un attribut .left pour dire que je veux que le bord gauche de mon enfant et parent soit aligné. Est-ce que cette logique est défectueuse ou est-ce que je fais quelque chose d'autre?

NSLayoutConstraint(item: customViewChild!, 
      attribute: .left, 
      relatedBy: .equal, 
      toItem: self, 
      attribute: .left, 
      multiplier: 1.0, 
      constant: 0.0) 

Je sais l'exemple suivant pourrait très facilement être fait avec IB, mais je suis en train de comprendre NSLayoutConstraint, donc s'il vous plaît fournir des réponses concernant cela. Et enfin, si quelqu'un pouvait réellement corriger ce code afin d'avoir un exemple concret, ce serait génial.

class CustomViewParent: UIView { 

    var customViewChild: UIView? 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     setConstraints() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 

     setConstraints() 
    } 

    func setConstraints() { 
     customViewChild = UIView() 

     addSubview(customViewChild!) 
     customViewChild?.translatesAutoresizingMaskIntoConstraints = false 

     let leftConstraint = NSLayoutConstraint(item: customViewChild!, 
      attribute: .left, 
      relatedBy: .equal, 
      toItem: self, 
      attribute: .left, 
      multiplier: 1.0, 
      constant: 0.0).isActive = true 

     let rightConstraint = NSLayoutConstraint(item: customViewChild!, 
      attribute: .right, 
      relatedBy: .equal, 
      toItem: self, 
      attribute: .right, 
      multiplier: 1.0, 
      constant: 0.0).isActive = true 

     let topConstraint = NSLayoutConstraint(item: customViewChild!, 
      attribute: .top, 
      relatedBy: .equal, 
      toItem: self, 
      attribute: .top, 
      multiplier: 1.0, 
      constant: 0.0).isActive = true 

     let bottomConstraint = NSLayoutConstraint(item: customViewChild!, 
      attribute: .bottom, 
      relatedBy: .equal, 
      toItem: self, 
      attribute: .bottom, 
      multiplier: 1.0, 
      constant: 0.0).isActive = true 

     customViewChild.addConstraint([leftConstraint, rightConstraint, topConstraint, bottomConstraint]); 
    } 

} 
+0

Débarrassez-vous de 'customViewChild.addConstraint. .. ». La définition de 'isActive' à true les ajoute aux bonnes vues. – vacawama

+0

Créez-vous l'instance de 'CustomViewParent' à partir d'un storyboard ou d'un fichier nib? Sinon, 'init (coder:)' n'est probablement pas appelé. Utilisez un point d'arrêt ou un journal pour confirmer. En outre, je vous suggère de nous diriger et de voyager plutôt que de prendre le large et le droit. – Paulw11

Répondre

1

Trois choses:

  1. Vous n'avez pas besoin d'utiliser addConstraint. Réglez simplement isActive à true pour les contraintes.
  2. Cela n'a aucun sens à la fois de définir isActive à true et d'affecter le résultat de cela à une constante. La définition de la propriété isActive ne renvoie pas le NSLayoutConstraint. Il renvoie (). Vous devez utiliser .leading et .trailing au lieu de .left et .right.

Avec ces changements, les éléments suivants devraient fonctionner:

func setConstraints() { 
    customViewChild = UIView() 

    addSubview(customViewChild!) 
    customViewChild?.translatesAutoresizingMaskIntoConstraints = false 

    NSLayoutConstraint(item: customViewChild!, 
     attribute: .leading, 
     relatedBy: .equal, 
     toItem: self, 
     attribute: .leading, 
     multiplier: 1.0, 
     constant: 0.0).isActive = true 

    NSLayoutConstraint(item: customViewChild!, 
     attribute: .trailing, 
     relatedBy: .equal, 
     toItem: self, 
     attribute: .trailing, 
     multiplier: 1.0, 
     constant: 0.0).isActive = true 

    NSLayoutConstraint(item: customViewChild!, 
     attribute: .top, 
     relatedBy: .equal, 
     toItem: self, 
     attribute: .top, 
     multiplier: 1.0, 
     constant: 0.0).isActive = true 

    NSLayoutConstraint(item: customViewChild!, 
     attribute: .bottom, 
     relatedBy: .equal, 
     toItem: self, 
     attribute: .bottom, 
     multiplier: 1.0, 
     constant: 0.0).isActive = true 
} 
1

Vous pouvez trouver cela un peu plus facile et plus facile à lire ...

func setConstraints() { 

    if customViewChild == nil { 
     customViewChild = UIView() 

     addSubview(customViewChild!) 
     customViewChild?.translatesAutoresizingMaskIntoConstraints = false 

     customViewChild?.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true 
     customViewChild?.topAnchor.constraint(equalTo: self.topAnchor).isActive = true 
     customViewChild?.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true 
     customViewChild?.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true 
    } 

}