简体   繁体   English

iOS:UIButton自动版式大小为零

[英]iOS: UIButton Autolayout size is zero

Using autolayout I want to understand why the following happens: Creating a simple UIButton and setting its title. 使用自动布局,我想了解为什么会发生以下情况:创建一个简单的UIButton并设置其标题。 However, even though I expect the intrinsic content size of the view to be set and hence get its frame properly - the frame of the button is showing (0, 0, 0, 0). 但是,即使我希望设置视图的固有内容大小并因此正确获取其框架,该按钮的框架也会显示(0,0,0,0)。 What do I have to do to get the frame value of the button ? 我该怎么做才能获取按钮的帧值?

-(void)viewDidLoad {

    [super viewDidLoad];

    UIButton *button = [[UIButton alloc] init];

    [button.titleLabel setText:@"My button"];

    //button frame is zero

}

Yet if I am to do that, then things work as expected: 但是,如果我要这样做,那么事情将会按预期进行:

-(void)viewDidLoad {

    [super viewDidLoad];

    UILabel *label = [[UILabel alloc] init];

    [label setText:@"My label"];

    [label sizeToFit];

    //label frame has the expected width and height

}

Autolayout sets views frame only after a layout pass, it's something that has cycle and is not called evertytime you add a view or modify constraints, that's why sometimes you need to call -setNeedsLayout on a particular view. 自动布局仅在布局通过后才设置视图框架,这是一个循环的过程,不会在每次添加视图或修改约束时被调用,这就是为什么有时需要在特定视图上调用-setNeedsLayout的原因。
The other point is that if you do not create constraints using interface builder or programmatically, autolayout automatically converts the view autoresizing masks into constraints ( -translatesAutoresizingMaskIntoConstraints property). 另一点是,如果你没有创建使用Interface Builder或以编程的限制,自动布局自动视图自动尺寸口罩转换成约束( -translatesAutoresizingMaskIntoConstraints属性)。
In this case if you set a text, you are forcing the view to express its intrinsic content size, that basically is the size of the label, if the intrinsic content size doesn't conflict to other constraints it wins, but you can only ask the button size after the layout pass. 在这种情况下,如果设置文本,则将强制视图表达其内在内容的大小,该大小基本上是标签的大小,如果内在内容的大小不与它赢得的其他约束冲突,但是您只能问布局通过后的按钮大小。 Try to check the button size inside .viewDidLayout after the call of the same method to the super class 在对超类调用相同方法后,尝试检查.viewDidLayout的按钮大小

- (void)viewDidLoad {
    [super viewDidLoad];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    button.translatesAutoresizingMaskIntoConstraints = NO;
    [button setTitle:@"My button" forState:UIControlStateNormal];
    [self.view addSubview:button];
}

- (void)viewDidLayoutSubviews {
    //check frame of button
}

Just like @Andrea said: because you haven't added the button in IB, it is defaulting to using the autoResizingMask, which will keep the zero sized frame that the button initialised with. 就像@Andrea所说的:因为您没有在IB中添加按钮,所以默认情况下使用autoResizingMask,它将保留按钮初始化时使用的零尺寸框架。

If you want autolayout to work, you need to set 如果要使用自动版式,则需要设置

button.translatesAutoresizingMaskIntoConstraints = NO;

right before calling -addSubview: . 就在调用-addSubview:之前。

In addition, you'll have to add at least 1 horizontal constraint and 1 vertical constraint, to position the button. 另外,您必须添加至少1个水平约束和1个垂直约束来放置按钮。 Even after you do that, the button's frame will only be set after the next layout pass, which you can manually initiate by calling -layoutIfNeeded . 即使执行了此操作,也仅在下一次布局通过之后设置按钮的框架,您可以通过调用-layoutIfNeeded手动启动-layoutIfNeeded

Add the button as a sub view and call layoutIfNeeded on the subview. 将按钮添加为子视图,然后在子视图上调用layoutIfNeeded Access its frame after that. 之后访问其框架。

Also make sure you add constraints for leading and top to position the button within its superview. 还要确保您添加了前导和顶部约束,以将按钮定位在其父视图内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM