web-dev-qa-db-fra.com

Où ajouter le code de contraintes de mise en page automatique dans une UIView personnalisée

Je vois souvent des contraintes de mise en page automatique ajoutées dans le UIViewController mais pour moi, cela ne semble pas être le bon endroit pour la logique de mise en page.

Est-il possible d'ajouter NSLayoutConstraints dans un UIView personnalisé?

Où dans un UIView serait le bon endroit pour les ajouter par programme?

26
Bernd

Est-il possible d'ajouter NSLayoutConstraints dans une UIView personnalisée?

Oui, il est possible d'ajouter des contraintes dans une vue personnalisée, l'organisation est très importante ici, surtout si vous souhaitez animer des parties de votre vue personnalisée.

Lisez la section de sous-classement d'Apple document de référence UIView

Contraintes:

requiresConstraintBasedLayout - Implémentez cette méthode de classe si votre classe de vue nécessite des contraintes pour fonctionner correctement.

updateConstraints - Implémentez cette méthode si votre vue doit créer des contraintes personnalisées entre vos sous-vues.

alignRectForFrame :, frameForAlignmentRect: - Implémentez ces méthodes pour remplacer la façon dont vos vues sont alignées sur d'autres vues.

Où dans une UIView est le bon endroit pour les ajouter par programme?

Voici un aperçu squelette d'une classe personnalisée. La principale préoccupation est que vous centralisez vos contraintes, sinon la classe devient très désordonnée plus vous ajoutez de contraintes. Vous pouvez également introduire d'autres paramètres dans la méthode updateConstraints () et ajouter ou supprimer conditionnellement des contraintes en définissant vos valeurs de configuration, puis appelez setNeedsUpdateConstraints ().

Toutes les contraintes que vous décidez d'animer doivent le plus légèrement être des variables d'instance.

J'espère que cela t'aides :)

class MyCustomView: UIView {

    private var didSetupConstraints = false
    private let myLabel = UILabel(frame: CGRectZero)

    // MARK: Lifecycle
    override init(frame: CGRect) {
        super.init(frame: CGRectZero)
        self.setup()
    }

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


    // Mark: - Setup
    private func setup() {

        // 1. Setup the properties of the view it's self
        self.translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = UIColor.orangeColor()
        clipsToBounds = true

        // 2. Setup your subviews
        setupMyLabel()

        // 3. Inform the contraints engine to update the constraints
        self.setNeedsUpdateConstraints()
    }


    private func setupMyLabel() {

        myLabel.translatesAutoresizingMaskIntoConstraints = false

    }


    override func updateConstraints() {

        if didSetupConstraints == false {
            addConstraintsForMyLabel()
        }

        super.updateConstraints() //Documentation note: Call [super updateConstraints] as the final step in your implementation.
    }

    private func addConstraintsForMyLabel() {

        // Add your constraints here
    }

}
33
Pete Hornsby

J'aime configurer mon code AutoLayout dans les vues quand cela a plus de sens. J'ai également constaté qu'il est plus facile de configurer toutes les contraintes en un seul endroit dans le cadre de l'initialisation de customView.

import UIKit

class customView:UIView
{
    var customLabel:UILabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setupUI()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupUI()
    {
        // Setup UI
        self.customLabel.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(customLabel)

        // Setup Constraints
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-10-[customLabel]|", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["customLabel":self.customLabel]))
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[customLabel]-10-|", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["customLabel":self.customLabel]))
    }
}
8
Joseph Afework