UIButton 上的标签未使用自动布局正确布局

Label on UIButton not laid out correctly with autolayout

我有一个正在更新为自动布局和大小 classes 的应用程序,我发现按钮上的标签出现一些奇怪的行为。

按钮应该是一个圆圈,中间有一个标签。我正在实现我自己的 subclass 以便我可以重用它。

故事板如下:

以及扩展 UIButton 的 class 的代码:

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    if (self) {
        [self setBackgroundImage:[UIImage imageNamed:@"selected-green"] forState:UIControlStateHighlighted                                                                                                                                                                                               ];

        self.layer.borderColor = [UIColor tlbWhiteColor].CGColor;
        self.layer.borderWidth = 10;

    }
    return self;
}

-(void) layoutSubviews {
    self.layer.cornerRadius = self.frame.size.width / 2;
}

有了这个,按预期显示,但没有标签。在调试时,我看到标签的框架的高度和宽度为 0。所以我扩展了 layoutSubviews:

-(void) layoutSubviews {
    self.layer.cornerRadius = self.frame.size.width / 2;
    if (self.titleLabel.frame.size.width == 0) {
        [self.titleLabel sizeToFit];
        [self setNeedsLayout];
        [self layoutIfNeeded];
    }

}

标签随即出现,但位置错误:

我能提供的唯一额外信息是,在 Reveal 中,按钮添加了奇怪的高度和宽度限制:

titleInsets 都为 0。

非常感谢帮助。

我认为您不需要覆盖 layoutSubviews。我认为这是一个 hack,它隐藏了你的真正问题。

'Go' 标签有哪些限制?你如何将它置于 UIButton 的中心?还有标签的高度限制是多少?

我的建议是将 UIButton 和 Go 标签都放在容器视图中,并将标签居中放置在容器视图中。容器视图应与其内部的 UIButton 具有相同的高度和宽度。

您是否也在应用程序中的某处以编程方式更改视图的框架?你谈到的那些奇怪的约束揭示了这一点。

根据您的要求:

   - (void)viewDidLoad {
    [super viewDidLoad];
    view_1.layer.cornerRadius = 10; //view_1 is white color
    view_1.layer.masksToBounds = YES;


    view_2.layer.cornerRadius = _view_2.frame.size.width/2;//view_2 is green color
    view_2.layer.masksToBounds = YES;
}

输出

好吧,这是一个真正的小学生错误。

当文档说 'The implementation of this method is empty before iOS 6' 时,我出于某种原因认为这意味着不需要在 layoutSubviews 上调用 super。

所以修复是:

-(void) layoutSubviews {
    [super layoutSubviews];  // <<<<< THIS WAS MISSING
    self.layer.cornerRadius = self.frame.size.width / 2;
    self.layer.masksToBounds = YES;
}