web-dev-qa-db-fra.com

Centrer UIView personnalisé verticalement et horizontalement à l'aide de la disposition automatique

J'essaie de créer une interface utilisateur personnalisée animée plutôt simple à l'aide de l'API de mise en page automatique nouvellement disponible iOS 6. La vue personnalisée que je construis a un cercle que je veux être à la fois centré verticalement et horizontalement.

Malheureusement, je ne peux pas comprendre pourquoi mes contraintes semblent fonctionner correctement pour les éléments UIButton et UILabel, mais donnent des résultats étranges lorsque j'utilise une vue personnalisée avec et CALayer personnalisé (dans ce cas, un cercle, qui sera finalement animé).

Pour être clair, je ne veux pas que ma vue se développe pour remplir tout l'écran, mais plutôt d'avoir un "rembourrage" dynamique afin que la vue soit centrée verticalement à la fois sur l'iPhone 4 et 5. Je dois également noter que je suis très nouveau sur Cocoa et UIKit.

RootViewController.m:

...
- (void)viewDidLoad {
    [super viewDidLoad];

    // Create Circle View
    CGRect circle_view_rect = CGRectMake(0, 0, 100, 100);
    UIView *circle_view = [[UIView alloc] initWithFrame:circle_view_rect];

    // Create Circle Layer
    CircleLayer *circle_layer = [[CircleLayer alloc] init];
    circle_layer.needsDisplayOnBoundsChange = YES;
    circle_layer.frame = circle_view.bounds;
    [circle_view.layer addSublayer:circle_layer];

    // Enable Auto Layout
    [circle_view setTranslatesAutoresizingMaskIntoConstraints:NO];

    [self.view addSubview:circle_view];

    // Center Vertically
    NSLayoutConstraint *centerYConstraint =
    [NSLayoutConstraint constraintWithItem:circle_view
                attribute:NSLayoutAttributeCenterY
                relatedBy:NSLayoutRelationEqual
                   toItem:self.view
                attribute:NSLayoutAttributeCenterY
               multiplier:1.0
                 constant:0.0];
    [self.view addConstraint:centerYConstraint];

    // Center Horizontally
    NSLayoutConstraint *centerXConstraint =
    [NSLayoutConstraint constraintWithItem:circle_view
                attribute:NSLayoutAttributeCenterX
                relatedBy:NSLayoutRelationEqual
                   toItem:self.view
                attribute:NSLayoutAttributeCenterX
               multiplier:1.0
                 constant:0.0];
    [self.view addConstraint:centerXConstraint];
}
...

CircleLayer.m:

...
- (void)drawInContext:(CGContextRef)context {
    CGContextAddArc(context, 50, 50, 50, 0.0, 2*M_PI, 0);
    CGContextSetFillColorWithColor(context, [UIColor yellowColor].CGColor);
    CGContextFillPath(context);
}
...

Fondamentalement, les contraintes que j'ai mises en place sont:

  • centrer verticalement à l'intérieur de la vue parent
  • centrer horizontalement à l'intérieur de la vue parent

Et voici le résultat que j'obtiens:

Circle not centered with Auto Layout

Toute aide serait grandement appréciée, je réfléchis à celle-ci depuis quelques jours maintenant.

Merci

30
phor2

Essayez d'ajouter une contrainte de hauteur et de largeur à votre cercle_vue. Je ne pouvais même pas obtenir une vue carrée de la douleur sans les ajouter (en utilisant votre code, moins les trucs de couche).

NSLayoutConstraint *heightConstraint =
    [NSLayoutConstraint constraintWithItem:circle_view
                                 attribute:NSLayoutAttributeHeight
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:nil
                                 attribute:NSLayoutAttributeNotAnAttribute
                                multiplier:1.0
                                  constant:100.0];
    [circle_view addConstraint:heightConstraint];

    NSLayoutConstraint *widthConstraint =
    [NSLayoutConstraint constraintWithItem:circle_view
                                 attribute:NSLayoutAttributeWidth
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:nil
                                 attribute:NSLayoutAttributeNotAnAttribute
                                multiplier:1.0
                                  constant:100.0];
    [circle_view addConstraint:widthConstraint];
34
rdelmar

Pour ajouter à la réponse de rdelmar:

Le problème principal est que dès que vous suivez la route NSLayoutConstraint et spécifiez setTranslatesAutoresizingMaskIntoConstraints:NO, le cadre que vous avez créé avec CGRectMake n'est plus pertinent pour la mise en page automatique. C'est pourquoi il n'a pas utilisé les informations de la hauteur et de la largeur du cadre.

12
Ben Wheeler