Swift 角半径未显示在带有@ibdesiable/@IBInspectable的故事板中的按钮上

Swift 角半径未显示在带有@ibdesiable/@IBInspectable的故事板中的按钮上,swift,uibutton,uistoryboard,ibdesignable,ibinspectable,Swift,Uibutton,Uistoryboard,Ibdesignable,Ibinspectable,我有一个按钮的自定义类 import UIKit @IBDesignable class CustomButton: UIButton { @IBInspectable var cornerRadiusValue: CGFloat = 10.0 { didSet { setUpView() } } required init?(coder aDecoder: NSCoder) { super.i

我有一个按钮的自定义类

import UIKit

@IBDesignable
class CustomButton: UIButton {

    @IBInspectable var cornerRadiusValue: CGFloat = 10.0 {
        didSet {
            setUpView()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.layer.cornerRadius = 10.0
    }

    override func awakeFromNib() {
        setUpView()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        setUpView()
    }

    func setUpView() {
        self.layer.cornerRadius = 10.0
    }

}
但是角半径没有显示在故事板的按钮上

我理解@IBInspectable只允许您更改inspector面板中的值。我想那不是我想要的


我想角半径只是显示在故事板时,我创建一个按钮与该类。我认为@IBDesignable就是这么做的。

您的代码在IB中崩溃了,所以可设计性失败了。下面是更简单的代码:

@IBDesignable
class CustomButton: UIButton {
    @IBInspectable var cornerRadiusValue: CGFloat = 10.0 {
        didSet {
            setUpView()
        }
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        setUpView()
    }
    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        setUpView()
    }
    func setUpView() {
        self.layer.cornerRadius = self.cornerRadiusValue
        self.clipsToBounds = true
    }
}
现在按钮既可检查又可设计:

它也可以在running应用程序中使用。

试试这个:

@IBDesignable
class CustomButton: UIButton {

    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
        }
    }

}

这里有一个比公认答案更好的解决方案:

@IBDesignable
class DesignableButton: UIButton {

    @IBInspectable private var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.masksToBounds = newValue > 0
            layer.cornerRadius = newValue
        }
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        setNeedsDisplay()
    }

}

它使用计算属性来避免与存储属性重复状态。

不知道它是否会解决,但您没有将层剪裁到其边界,您可能需要这样做,以便它至少在运行时显示。“故事板”中的“不确定”补充了这一点,但没有解决我想要的问题。不过谢谢你。问题是你的代码在IB中崩溃了,所以设计性失败了。我提供了一个不会崩溃的代码版本,所以它可以正常工作。你能说明我的答案是怎么错的吗?正如您所说:“您真的尝试过这个吗?它在情节提要中绕过了各个角落吗?”非常有用,您可以在didSet上调用
setUpView()
,而不是在类的init上调用它。这就解决了问题。谢谢。您只需在
prepareForInterfaceBuilder()
中调用
setNeedsDisplay()
,删除
awakeFromNib()
的实现,并直接在
didSet
中更新角半径的逻辑。如果要设置层边框宽度,应为其创建单独的值,就像拐角半径一样。设置角半径不应修改其他属性。这会产生误导,并导致意大利面代码。这将违反称为正交性的原则。您的答案将在属性观察器中设置clipsToBounds。它只是让它有点模糊
cornerRadiusValue
是一个不必要的冗余名称<代码>设置视图是一个误导性的名称。您的答案通过使用存储属性添加了不必要的状态。