【问题标题】:Subclass with IBInspectable color property - override not possible具有 IBInspectable 颜色属性的子类 - 无法覆盖
【发布时间】:2019-04-28 08:14:33
【问题描述】:

我有一个带有 IBInspectable 颜色属性的自定义 UIView 类:

class MyParent: UIView {
    // use CGColor for setting background (a gradient), and IBInspectable UIColor to choose color in Interface Builder
    var color1: CGColor = UIColor(red: 100.0/255.0, green: 130.0/255.0, blue: 230.0/255.0, alpha: 1.0).CGColor
    var color2: CGColort = UIColor(red: 200.0/255.0, green: 30.0/255.0, blue: 30.0/255.0, alpha: 1.0).CGColor
    @IBInspectable var UIcolor1: UIColor = UIColor(red: 100.0/255.0, green: 130.0/255.0, blue: 230.0/255.0, alpha: 1.0) {
        didSet {
            color1 = UIcolor1.cgColor
        }
    }

    // INIT: Set gradient with color1/2 for the background of MyParent view
    override init(frame: CGRect) {
        super.init(frame: frame);
        var gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = [color1, color2]
        layer.insertSublayer(gradient, at: 0)
    }
}

澄清更新: 这样做是为了能够在 Interface Builder 中选择颜色(只能使用 UIColor),但是由于视图的背景是渐变的,它需要转换成CGColor。因此 didSet 完成了这项工作,并且在 IB 中选择了一个 UIColor 后,背景分别发生了变化。

现在我想要另一个自定义 UIView,它是 MyParent 的子类,我想设置另一个默认 UIcolor1,但我收到错误:

class MySubclass: MyParent {
    // override UIcolor1
    override var UIcolor1: UIColor = UIColor.blue

    // ...
}

以下错误:

Cannot override the stored property 'UIcolor1'

我怎样才能让它工作?

【问题讨论】:

    标签: swift subclass


    【解决方案1】:

    如果您不想在初始化时设置颜色,我认为您可以在这里做的最好的事情

    class MySubclass: MyParent {
    // override UIcolor1
      override var UIcolor1: UIColor {
          get {
              return .blue
          }
          set {
              color1 = newValue.cgColor
          }
       }
    // ...
    }
    

    代码编辑后

    我认为没有必要对视图进行子类化。这是工作代码

    @IBDesignable
    class MyParent: UIView {
        // use CGColor for setting background, and IBInspectable UIColor to choose color in Interface Builder
        var color1: UIColor = UIColor.blue {
            didSet {
                gradientLayer.colors = [color1.cgColor, color2]
            }
        }
    
       var color2: CGColor = UIColor.green.cgColor
    
       @IBInspectable var inspectableColor1: UIColor {
           get {
               return color1
           }
           set {
               color1 = newValue
           }
       }
    
       private var gradientLayer = CAGradientLayer()
       // INIT: Set color1 for the background of MyParent view
       // ...
       override init(frame: CGRect) {
          super.init(frame: frame)
          setupLayer()
       }
    
       required init?(coder aDecoder: NSCoder) {
          super.init(coder: aDecoder)
          setupLayer()
      }
    
      func setupLayer() {
          gradientLayer.frame = bounds
          gradientLayer.colors = [color1.cgColor, color2]
          layer.insertSublayer(gradientLayer, at: 0)
      }
    }
    

    【讨论】:

    • 不幸的是,这不起作用。虽然它消除了错误,但它会将属性更改为计算属性,并且父类中的 didSet 不再起作用(如果在 IB 中更改颜色,则不再更新)
    • 我已经编辑了我的代码,添加到 setter color1 = newValue.cgColor 这应该可以满足您的要求
    • 我这样做了,但是如果我在 IB 中更改颜色,则没有任何反应
    • 究竟需要做什么?
    • 请查看我更新的帖子:我添加了 init,其中设置了渐变。那么应该发生的是,子类的新设置(在 IB 中)UIColor1 会更改 color1 值,然后 IB 会将视图的背景更新为新颜色
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多