ios 使用自动布局垂直和水平居中自定义 UIView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13726929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:26:08  来源:igfitidea点击:

Center custom UIView vertically and horizontally using Auto Layout

ioscocoa-touchuiviewcalayerautolayout

提问by phor2

I'm trying to build a rather simple animated custom UI using the Auto Layout API newly available iOS 6. The custom view I'm building has a circle that I want to be both vertically and horizontally centered.

我正在尝试使用最新可用的 iOS 6 自动布局 API 构建一个相当简单的动画自定义 UI。我正在构建的自定义视图有一个圆,我希望它垂直和水平居中。

Unfortunately I can't figure out why my constraints appear to work fine for UIButton, and UILabel elements but yield weird results when I use a custom view with and custom CALayer (in this case a circle, that will eventually be animated).

不幸的是,我无法弄清楚为什么我的约束对于 UIButton 和 UILabel 元素似乎可以正常工作,但是当我使用自定义视图和自定义 CALayer 时会产生奇怪的结果(在这种情况下是一个圆圈,最终会被动画化)。

To be clear I don't want my view to expand to fill the whole screen, but rather to have dynamic "padding" so that the view is vertically centered both on the iPhone 4 and 5. I should also note that I'm very new to Cocoa and UIKit.

明确地说,我不希望我的视图扩展以填满整个屏幕,而是希望具有动态“填充”,以便视图在 iPhone 4 和 5 上垂直居中。我还应该注意,我非常Cocoa 和 UIKit 的新手。

RootViewController.m:

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:

圆层.m:

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

Basically the constraints I've implemented are:

基本上我实施的约束是:

  • center vertically inside parent view
  • center horizontally inside parent view
  • 在父视图内垂直居中
  • 在父视图内水平居中

And this is the result I get:

这是我得到的结果:

Circle not centered with Auto Layout

圆不以自动布局居中

Any help would be greatly appreciated, I've been pondering this one for a few days now.

任何帮助将不胜感激,我一直在思考这个问题几天了。

Thanks

谢谢

回答by rdelmar

Try adding a height and width constraint to your circle_view. I couldn't even get just a pain square view to appear at all without adding those (using your code, minus the layer stuff).

尝试向您的 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];

回答by Ben Wheeler

Just to add to rdelmar's answer:

只是添加到 rdelmar 的答案中:

The core issue is that as soon as you go the NSLayoutConstraintroute, and specify setTranslatesAutoresizingMaskIntoConstraints:NO, the frame you made with CGRectMakeis rendered irrelevant for AutoLayout purposes. That's why it didn't use the info from the frame's height and width.

核心问题是,只要您走这NSLayoutConstraint条路线并指定setTranslatesAutoresizingMaskIntoConstraints:NO,您制作的框架就会CGRectMake呈现为与 AutoLayout 目的无关。这就是为什么它没有使用框架高度和宽度的信息。