web-dev-qa-db-fra.com

Comment centrer une sous-vue de UIView

J'ai un UIView dans un UIViewm et je veux que le UIView soit toujours centré dans celui qui est à l'extérieur, sans qu'il ait à redimensionner la largeur et la hauteur.

J'ai réglé les jambes de force et les ressorts de manière à ce que ce soit en haut/à gauche/à droite/en bas sans régler le redimensionnement. Mais ça ne centre toujours pas. Une idée?

118
xonegirlz

Objectif c

yourSubView.center = CGPointMake(yourView.frame.size.width  / 2, 
                                 yourView.frame.size.height / 2);

Swift

yourSubView.center = CGPoint(x: yourView.frame.size.width  / 2,
                             y: yourView.frame.size.height / 2)
190
happy pig

Vous pouvez le faire et cela fonctionnera toujours:

child.center = [parent convertPoint:parent.center fromView:parent.superview];

Et pour Swift:

child.center = parent.convert(parent.center, from:parent.superview)
271
Hejazi

Avant de commencer, rappelons simplement que le point d'origine est le coin supérieur gauche CGPoint d'une vue. Une chose importante à comprendre sur les points de vue et les parents.

Jetons un coup d'oeil à ce code simple, un contrôleur de vue qui ajoute à sa vue un carré noir:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        createDummyView()
        super.view.backgroundColor = UIColor.cyanColor();
    }

    func createDummyView(){
        var subView = UIView(frame: CGRect(x: 15, y: 50, width: 50 , height: 50));
        super.view.addSubview(subView);
        view.backgroundColor = UIColor.blackColor()
    }

}

Cela créera cette vue: le rectangle noir Origine et centre correspond aux mêmes coordonnées que son parent

enter image description here

Essayons maintenant d’ajouter une autre vue SubSubView à SubView, en donnant à SubSubview la même origine que SubView, mais faire de SubSubView une vue enfant de SubView.

Nous allons ajouter ce code:

var subSubView = UIView();
subSubView.frame.Origin = subView.frame.Origin;
subSubView.frame.size = CGSizeMake(20, 20);
subSubView.backgroundColor = UIColor.purpleColor()
subView.addSubview(subSubView)

Et voici le résultat:

enter image description here

A cause de cette ligne:

subSubView.frame.Origin = subView.frame.Origin;

Vous vous attendez à ce que l'origine du rectangle violet soit identique à celle de son parent (le rectangle noir), mais il passe en dessous et pourquoi? Parce que lorsque vous ajoutez une vue à une autre vue, le cadre de la sous-vue "monde" est maintenant son parent lié, si vous avez une vue indiquant que son origine sur l'écran principal est à coords (15,15) pour toutes ses sous-vues, le coin supérieur gauche sera (0,0)

C'est pourquoi vous devez toujours faire référence à un parent par son rectangle lié, qui est le "monde" de ses sous-vues, corrigeons cette ligne pour:

subSubView.frame.Origin = subView.bounds.Origin;

Et voyez la magie, la sous-vue est maintenant située exactement dans son parent d'origine:

enter image description here

Alors tu aimes "ok je voulais seulement centrer mon point de vue sur celui de mes parents, quel est le problème?" Eh bien, ce n'est pas grave, il vous suffit de "traduire" le point central du parent qui est pris de son cadre vers le centre des limites du parent en procédant comme suit:

subSubView.center = subView.convertPoint(subView.center, fromView: subSubView);

Vous lui dites en fait "prenez le point de vue des parents et convertissez-le en monde SubSubView".

Et vous obtiendrez ce résultat:

enter image description here

35
Daniel Krom

J'utiliserais:

self.childView.center = CGPointMake(CGRectGetMidX(self.parentView.bounds),
                                    CGRectGetMidY(self.parentView.bounds));

J'aime utiliser les options CGRect ...

Swift 3:

self.childView.center = CGPoint(x: self.parentView.bounds.midX,
                                        y: self.parentView.bounds.midY);
26
theprojectabot

1. Si l'autolayout est activé:

  • Conseil: pour centrer une vue sur une autre vue avec autolayout, vous pouvez utiliser le même code pour deux vues partageant au moins une vue parent.

Tout d'abord, désactivez le redimensionnement automatique des vues enfants

UIView *view1, *view2;
[childview setTranslatesAutoresizingMaskIntoConstraints:NO];
  1. Si vous êtes UIView + Autolayout ou Purelayout :

    [view1 autoAlignAxis:ALAxisHorizontal toSameAxisOfView:view2];
    [view1 autoAlignAxis:ALAxisVertical toSameAxisOfView:view2];
    
  2. Si vous utilisez uniquement des méthodes de calcul automatique du niveau UIKit:

    [view1 addConstraints:({
        @[ [NSLayoutConstraint
           constraintWithItem:view1
           attribute:NSLayoutAttributeCenterX
           relatedBy:NSLayoutRelationEqual
           toItem:view2
           attribute:NSLayoutAttributeCenterX
           multiplier:1.f constant:0.f],
    
           [NSLayoutConstraint
            constraintWithItem:view1
            attribute:NSLayoutAttributeCenterY
            relatedBy:NSLayoutRelationEqual
            toItem:view2
            attribute:NSLayoutAttributeCenterY
            multiplier:1.f constant:0.f] ];
    })];
    

2. Sans autolayout:

Je préfère:

UIView *parentView, *childView;
[childView setFrame:({
    CGRect frame = childView.frame;

    frame.Origin.x = (parentView.frame.size.width - frame.size.width) / 2.0;
    frame.Origin.y = (parentView.frame.size.height - frame.size.height) / 2.0;

    CGRectIntegral(frame);
})];
18
Cemal Eker

Le moyen le plus simple:

child.center = parent.center
12
juancazalla

enter image description here

Définissez ce masque de redimensionnement automatique sur votre vue intérieure.

8
Mayank Jain

Avec IOS9, vous pouvez utiliser l'API d'ancrage de mise en page.

Le code ressemblerait à ceci:

childview.centerXAnchor.constraintEqualToAnchor(parentView.centerXAnchor).active = true
childview.centerYAnchor.constraintEqualToAnchor(parentView.centerYAnchor).active = true

L’avantage de ceci par rapport à CGPointMake ou CGRect est qu’avec ces méthodes, vous définissez le centre de la vue sur une constante, mais avec cette technique, vous définissez une relation entre les deux vues qui durera toujours, peu importe comment la parentview change.

Assurez-vous juste avant de faire ceci:

        self.view.addSubview(parentView)
        self.view.addSubView(chidview)

et pour définir la valeur translatesAutoresizingMaskIntoConstraints de chaque vue sur false.

Cela évitera les plantages et l’interposition automatique.

7
Roymunson

Vous pouvez utiliser

yourView.center = CGPointMake(CGRectGetMidX(superview.bounds), CGRectGetMidY(superview.bounds))

Et dans Swift 3.0

yourView.center = CGPoint(x: superview.bounds.midX, y: superview.bounds.midY)
7
Sayali Shinde

Utiliser le même centre dans la vue et la sous-vue est la manière la plus simple de le faire. Vous pouvez faire quelque chose comme ça,

UIView *innerView = ....;
innerView.view.center = self.view.center;
[self.view addSubView:innerView];
5
codeFood

Une autre solution avec PureLayout en utilisant autoCenterInSuperview.

// ...
UIView *innerView = [UIView newAutoLayoutView];
innerView.backgroundColor = [UIColor greenColor];
[innerView autoSetDimensionsToSize:CGSizeMake(100, 30)];

[outerview addSubview:innerView];

[innerView autoCenterInSuperview];

Voilà à quoi ça ressemble:

Center with PureLayout

3
H6.

J'utiliserais:

child.center = CGPointMake(parent.bounds.height / 2, parent.bounds.width / 2)

C'est simple, court et doux. Si vous utilisez la réponse de @ Hejazi ci-dessus et que parent.center est réglé sur autre chose que (0,0) votre sous-vue ne sera pas centrée!

1
Old Name

En c # ou Xamarin.ios, on peut utiliser comme ceci

imageView.Center = new CGPoint (tempView.Frame.Size.Width/2, tempView.Frame.Size.Height/2);

1
func callAlertView() {

    UIView.animate(withDuration: 0, animations: {
        let H = self.view.frame.height * 0.4
        let W = self.view.frame.width * 0.9
        let X = self.view.bounds.midX - (W/2)
        let Y = self.view.bounds.midY - (H/2)
        self.alertView.frame = CGRect(x:X, y: Y, width: W, height: H)
        self.alertView.layer.borderWidth = 1
        self.alertView.layer.borderColor = UIColor.red.cgColor
        self.alertView.layer.cornerRadius = 16
        self.alertView.layer.masksToBounds = true
        self.view.addSubview(self.alertView)

    })


}// calculation works adjust H and W according to your requirement
0
Sidd Redkar