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

8

我将在应用程序中使用几个不同的圆形按钮(甚至是完全圆形的按钮),从我所知,实现这一点最简单的方法是设置按钮CALayer的cornerRadius属性。

然而,我不想为每个需要它的按钮在每个控制器中手动执行此操作,因此我认为一个简单的子类在初始化时设置这个属性是正确的方法。

我正在使用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)
    }
}

但我发现在这一点上(即init),无论框架还是边界的大小都不是最终确定的。对于Storyboard中大小(和约束)为H40 x W40的按钮,bounds/frame大小显示为H30 x W38。
这意味着cornerRadius没有得到我期望的值。
我确认在稍后的某个时刻(例如当按钮已经可以响应点击时),其frame/bounds确实为H40 x W40。
所以,在所有这些之后,我的问题是:在UIButton子类中,什么时候/在哪里可以安全地使用实例的最终frame/bounds值设置cornerRadius?
3个回答

21

如果您想在视图通过AutoLayout后执行代码,则必须在调用super.layoutSubviews()之后,在layoutSubviews方法中执行。

像这样:

class RoundedButton: UIButton {

    override func layoutSubviews() {
        super.layoutSubviews()

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

这段代码还不够完美,因为它不支持高度大于宽度的情况(不过很容易修复)。


1
由于所有答案都是相同的,而你的回答最先,我会接受你的回答。谢谢。实际上我没有提到我之所以只关心高度而不关心宽度的原因是因为我知道所有的按钮都将是正方形或水平矩形。但是,更一般化的解决方案应该寻找两个维度中较小的一个。 - RobertoCuba
这可能会被多次调用,不必要地一遍又一遍地设置值。FYI - Aaron

1

在Button类中尝试这个。

override func layoutSubviews() {
    super.layoutSubviews()

    // here...
}

1

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

在Objective-C中,您可以编写以下代码:

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

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接