web-dev-qa-db-ja.com

自動レイアウトを使用してカスタムUIViewを垂直および水平に中央揃え

IOS 6で新たに利用可能になったAuto Layout APIを使用して、かなりシンプルなアニメーションカスタムUIを構築しようとしています。構築中のカスタムビューには、垂直と水平の両方の中心に配置する円があります。

残念ながら、UIButtonおよびUILabel要素に対して制約が適切に機能しているように見えるのに、カスタムビューとカスタムCALayer(この場合は最終的にアニメーション化される円)を使用すると、奇妙な結果が生じる理由がわかりません。

明確にするために、ビューを画面全体に拡大するのではなく、動的な「パディング」を使用して、ビューがiPhone 4と5の両方で垂直方向の中央にくるようにします。 Cocoaおよび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);
}
...

基本的に、実装した制約は次のとおりです。

  • 親ビュー内の垂直方向の中央
  • 親ビュー内の水平方向の中央

そして、これは私が得る結果です:

Circle not centered with Auto Layout

助けていただければ幸いです。私はこの問題を数日間熟考してきました。

ありがとう

30
phor2

Circle_viewに高さと幅の制​​約を追加してみてください。それらを追加せずに(レイヤーの要素を除いてコードを使用して)ペインスクエアビューを表示することさえできませんでした。

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

Rdelmarの答えに追加するだけです:

中心的な問題は、NSLayoutConstraintルートに移動してすぐにsetTranslatesAutoresizingMaskIntoConstraints:NOCGRectMakeで作成したフレームは、AutoLayoutの目的には無関係にレンダリングされます。それがフレームの高さと幅からの情報を使用しなかった理由です。

12
Ben Wheeler