【问题标题】:Corner radius not showing on button in storyboard with @IBDesigable/@IBInspectable带有@IBDesigable/@IBInspectable 的情节提要中的按钮上未显示角半径
【发布时间】:2016-04-21 03:33:41
【问题描述】:

我有一个按钮的自定义类。

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 仅允许您更改检查器面板中的值。我想那不是我要找的。

当我使用该类创建按钮时,我希望角半径仅显示在情节提要中。我认为这就是@IBDesignable 所做的。

【问题讨论】:

  • 不知道它是否会解决,但您没有将图层裁剪到您可能需要做的边界,以便它至少在运行时显示。不确定在故事板中
  • 添加了它并没有解决我想要的问题。不过谢谢。
  • 问题是您的代码在 IB 中崩溃,因此可设计性失败。我提供了一个不会崩溃的代码版本,因此它可以按预期工作。

标签: swift uibutton uistoryboard ibdesignable ibinspectable


【解决方案1】:

您的代码在 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
    }
}

现在按钮既可检查又可设计:

它也适用于正在运行的应用程序。

【讨论】:

  • 你能具体说明我的答案是怎么错的吗?正如你所说:“你真的尝试过这个吗?它是否绕过故事板的角落?”
  • 在 didSet 而不是类的 init 上调用 setUpView() 非常有用。解决了这个问题。谢谢。
  • 你可以在prepareForInterfaceBuilder()中调用setNeedsDisplay(),去掉awakeFromNib()的实现,直接在didSet中实现更新圆角半径的逻辑。
  • 如果你想设置图层边框宽度,你应该为它创建一个单独的值,就像圆角半径一样。设置拐角半径不应修改其他属性。这会产生误导并导致意大利面条代码。这将违反称为正交性的原则。
  • 您的答案在属性观察器中设置了 clipsToBounds。它只是稍微混淆了它。 cornerRadiusValue 是一个不必要的冗余名称。 setUpView 是一个具有误导性的名称。您的答案通过使用存储属性添加了不必要的状态。
【解决方案2】:

试试这个:

@IBDesignable
class CustomButton: UIButton {

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

}

【讨论】:

    【解决方案3】:

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

    @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()
        }
    
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多