在子类中根据 UIButton 大小设置 cornerRadius 的最佳位置?

Best place to set cornerRadius based on UIButton size in subclass?

所以我将在应用程序中使用一些不同的圆形按钮(一直到圆形按钮),据我所知,实现此目的的最简单方法是设置 cornerRadius 属性按钮 CALayer.

但是,我不想为每个控制器中需要它的每个按钮手动执行此操作,所以我认为在初始化时设置它的简单子类就是这种方式。

我正在使用 Storyboard 和 Autolayout 来定位和调整按钮的大小,并将它们分配给这个子类。

class RoundedButton: UIButton {

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.layer.cornerRadius = self.bounds.size.height / 2.0
        self.clipsToBounds = true
        NSLog("BUTTON BOUNDS: H-%f  W-%f", self.bounds.size.height, self.bounds.size.width)
        NSLog("BUTTON FRAME: H-%f  W-%f", self.frame.height, self.frame.width)
    }
}

但我发现在这一点上(即初始化),框架和边界的大小都不是最终的。对于 Storyboard 中尺寸为(和约束)为 H40 x W40 的按钮,bounds/frame 尺寸显示为 H30 x W38。

这意味着 cornerRadius 没有得到我期望的值。

我已经确认在稍后的某个时候(例如当按钮已经可以响应点击时)它的 frame/bounds 确实是 H40 x W40。

所以毕竟,我的问题是,在 UIButton 子类中,when/where 我可以使用实例的最终 frame/bounds 值安全地设置 cornerRadius 吗?

如果您希望您的代码在视图通过 AutoLayout 之后执行,您必须在调用 super.layoutSubviews().

之后在 layoutSubviews 中执行此操作

像这样:

class RoundedButton: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

        layer.cornerRadius = bounds.size.height / 2.0
        clipsToBounds = true
    }
}

这段代码并不完美,因为当高度大于宽度时它不支持(虽然很容易修复……)。

在按钮 class 中试试这个。

override func layoutSubviews() {
    super.layoutSubviews()

    // here...
}

由于您希望使用 initWithCoder 而不是 initWithFrame(您确实拥有 frame 结构),因此您可以重写 layoutSubviews 方法。 当调用 layoutSubviews 时框架是正确的。

在objective-c中你可以写

- (void)layoutSubviews {
    [super layoutSubviews];
    self.layer.cornerRadius = self.bounds.size.height/2;

}