web-dev-qa-db-fra.com

iOS - Positionnez UIView au centre de la vue d'ensemble à l'aide de la mise en page automatique par programmation

Comment définir par programmation une UIView pour qu'elle soit au centre de sa vue d'ensemble à l'aide de la disposition automatique?

UIButton* viewObj = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[viewObj setTranslatesAutoresizingMaskIntoConstraints:NO];
[viewObj setBackgroundColor:[UIColor greenColor]];
[self.view addSubview:viewObj];

NSLayoutConstraint* cn = [NSLayoutConstraint constraintWithItem:viewObj
                                                      attribute:NSLayoutAttributeCenterX
                                                      relatedBy:NSLayoutRelationEqual
                                                         toItem:self.view
                                                      attribute:NSLayoutAttributeCenterX 
                                                     multiplier:1.0
                                                       constant:0];
[self.view addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj 
                                  attribute:NSLayoutAttributeCenterY
                                  relatedBy:NSLayoutRelationEqual 
                                     toItem:self.view
                                  attribute:NSLayoutAttributeCenterY
                                 multiplier:1.0
                                   constant:0];
[self.view addConstraint:cn];

Le code ci-dessus fonctionne pour moi pour UIButton, mais j'ai du mal à remplacer la première ligne par quelque chose qui fonctionne pour une UIView.

J'ai essayé

UIView* viewObj = [UIView alloc] initWithFrame:CGRectZero];

mais la vue n'apparaît pas dans le simulateur.

Aucune suggestion?

Merci!

26
Rohan Agarwal

Puisque vous avez posé cette question dans le contexte de l'utilisation de la mise en page automatique, le problème ici est qu'un UIButton a une taille intrinsèque (communiquée via la méthode intrinsicContentSize) qui fournit à Auto Layout des informations sur la largeur et la hauteur, mais pas une UIView normalement. Vous devez donc ajouter plus de contraintes liées à la largeur et à la hauteur.

Si vous voulez que votre UIView ait une taille définie (disons, 200x200), vous pouvez ajouter ces lignes:

cn = [NSLayoutConstraint constraintWithItem:viewObj 
                                  attribute:NSLayoutAttributeHeight
                                  relatedBy:NSLayoutRelationEqual 
                                     toItem:nil
                                  attribute:NSLayoutAttributeNotAnAttribute 
                                 multiplier:1
                                   constant:200];
[viewObj addConstraint:cn];

cn = [NSLayoutConstraint constraintWithItem:viewObj
                                  attribute:NSLayoutAttributeWidth
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:nil
                                  attribute:NSLayoutAttributeNotAnAttribute 
                                 multiplier:1 
                                   constant:200];
[viewObj addConstraint: cn];

Notez que l'argument toItem: Est nil et le deuxième attribut est NSLayoutAttributeNotAnAttribute, car vous ne spécifiez pas la largeur et la hauteur par rapport à autre chose. Si vous souhaitez que la hauteur et la largeur de la sous-vue soient relatives à la vue d'ensemble (par exemple, 0,5), vous pouvez le faire:

cn = [NSLayoutConstraint constraintWithItem:viewObj
                                  attribute:NSLayoutAttributeHeight
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                  attribute:NSLayoutAttributeHeight 
                                 multiplier:0.5 
                                   constant:0];
[self.view addConstraint:cn];
cn = [NSLayoutConstraint constraintWithItem:viewObj
                                  attribute:NSLayoutAttributeWidth
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                  attribute:NSLayoutAttributeWidth
                                 multiplier:0.5
                                   constant:0];
[self.view addConstraint: cn];
21
Peter E

UIButton, UIImageView, UIlabel et UITextField peuvent définir automatiquement leur taille en fonction de leurs propriétés de contenu. La largeur et la hauteur d'un UIImageView sont définies par le UIImage qu'il peut contenir. La taille d'un UILabel dépendra de son texte. La largeur et la hauteur d'un UIButton sont définies par le titre et l'image qu'il contient (vous pouvez en savoir plus à ce sujet avec Taille du contenu intrinsèque ).

Par conséquent, lorsque vous souhaitez centrer un UIButton, un UILabel, un UITextField ou un UIImageView dans un UIView avec mise en page automatique, dans presque tous les cas, vous n'avez pas à créer de contraintes pour leur largeur et leur hauteur. Il vous suffit de définir des contraintes horizontales et verticales pour eux.

Cependant, avec la disposition automatique, un UIView qui n'a pas de sous-vues ne peut pas compter sur quoi que ce soit pour définir sa taille, sauf si vous lui fournissez des contraintes arbitraires de largeur et de hauteur. Et selon vos besoins, vous pouvez résoudre ce problème de 3 manières différentes.


Le style de disposition automatique pur

Ici, nous définissons la largeur et la hauteur de notre UIView directement comme contraintes de disposition automatique:

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView()
    newView.backgroundColor = .redColor()
    newView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(newView)

    // Auto layout code using anchors (iOS9+)
    let horizontalConstraint = newView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor)
    let verticalConstraint = newView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor)
    let widthConstraint = newView.widthAnchor.constraintEqualToAnchor(nil, constant: 100)
    let heightConstraint = newView.heightAnchor.constraintEqualToAnchor(nil, constant: 100)
    NSLayoutConstraint.activateConstraints([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}

Le style de masque de redimensionnement automatique

Ici, nous initialisons notre UIView avec sa largeur et sa hauteur, rendons son centre et son centre de superview égaux et créons des masques de redimensionnement automatique. Ensuite, nous demandons à UIKit de traduire ces masques de redimensionnement automatique en contraintes de disposition automatique:

override func viewDidLoad() {
    super.viewDidLoad()

    let newView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
    newView.backgroundColor = .redColor()

    newView.center = CGPointMake(view.bounds.midX, view.bounds.midY)
    newView.autoresizingMask = [.FlexibleLeftMargin, .FlexibleRightMargin, .FlexibleTopMargin, .FlexibleBottomMargin]

    newView.translatesAutoresizingMaskIntoConstraints = true // default is true
    view.addSubview(newView)
}

Le style de sous-classe

Ici, nous créons une sous-classe de UIView et remplaçons sa méthode intrinsicContentSize() ( declaration ) afin qu'elle renvoie la taille souhaitée:

import UIKit

class CustomView: UIView {
    override func intrinsicContentSize() -> CGSize {
        return CGSize(width: 100, height: 100)
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let newView = CustomView()
        newView.backgroundColor = .redColor()
        newView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(newView)

        let horizontalConstraint = NSLayoutConstraint(item: newView,
            attribute: .CenterX,
            relatedBy: .Equal,
            toItem: view,
            attribute: .CenterX,
            multiplier: 1,
            constant: 0)
        view.addConstraint(horizontalConstraint)
        let verticalConstraint = NSLayoutConstraint(item: newView,
            attribute: .CenterY,
            relatedBy: .Equal,
            toItem: view,
            attribute: .CenterY,
            multiplier: 1,
            constant: 0)
        view.addConstraint(verticalConstraint)
    }

}
5
Imanou Petit