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 NSLayoutConstraint
s dans un UIView
personnalisé?
Où dans un UIView
serait le bon endroit pour les ajouter par programme?
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
}
}
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]))
}
}