iOS: UIButton 自动布局大小为零

iOS: UIButton Autolayout size is zero

使用自动布局我想了解为什么会发生以下情况:创建一个简单的 UIButton 并设置其标题。但是,即使我希望设置视图的固有内容大小并因此正确获取其框架 - 按钮的框架显示为 (0, 0, 0, 0)。我需要做什么才能获得按钮的帧值?

-(void)viewDidLoad {

    [super viewDidLoad];

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

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

    //button frame is zero

}

然而,如果我要那样做,那么事情就会按预期进行:

-(void)viewDidLoad {

    [super viewDidLoad];

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

    [label setText:@"My label"];

    [label sizeToFit];

    //label frame has the expected width and height

}

将按钮添加为子视图并在子视图上调用 layoutIfNeeded。之后访问其框架。

还要确保为 leading 和 top 添加约束以将按钮定位在其父视图中。

Autolayout 仅在布局通过后设置视图框架,它具有循环且不会在每次添加视图或修改约束时调用,这就是为什么有时您需要在特定视图上调用 -setNeedsLayout 的原因。
另一点是,如果您不使用界面构建器或以编程方式创建约束,自动布局会自动将视图自动调整大小掩码转换为约束(-translatesAutoresizingMaskIntoConstraints 属性)。
在这种情况下,如果您设置文本,您将强制视图表达其内在内容大小,基本上就是标签的大小,如果内在内容大小不与其他约束冲突,它会获胜,但您只能询问布局通过后的按钮大小。在对 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
}

正如@Andrea 所说:因为您没有在 IB 中添加按钮,所以它默认使用 autoResizingMask,这将保留按钮初始化时使用的零尺寸框架。

如果你想让自动布局工作,你需要设置

button.translatesAutoresizingMaskIntoConstraints = NO;

就在调用 -addSubview: 之前。

此外,您必须至少添加 1 个水平约束和 1 个垂直约束才能定位按钮。即使在您这样做之后,按钮的框架也只会在下一次布局通过后设置,您可以通过调用 -layoutIfNeeded.

手动启动