具有 IBInspectable 颜色属性的子类 - 无法覆盖

Posted

技术标签:

【中文标题】具有 IBInspectable 颜色属性的子类 - 无法覆盖【英文标题】:Subclass with IBInspectable color property - override not possible 【发布时间】: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'

我怎样才能让它工作?

【问题讨论】:

【参考方案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 会将视图的背景更新为新颜色

以上是关于具有 IBInspectable 颜色属性的子类 - 无法覆盖的主要内容,如果未能解决你的问题,请参考以下文章

为啥标记为@IBInspectable 的属性不起作用?

IBDesignable UIButton 子类

如何使用 @IBDesignable 和 @IBInspectable 制作 uitextfield 的自定义子类并在那里我可以从左侧设置占位符填充

配置 @IBInspectable 属性检查器控件

IBInspectable 属性值未在 xib 中更新

UIButton 子类中的 imageview.transform 奇怪的行为