【问题标题】:Swift: Share methods and computed properties across classes that do not inherit from one anotherSwift:在不相互继承的类之间共享方法和计算属性
【发布时间】:2016-08-23 05:34:01
【问题描述】:

我有三个 Swift 类:

@IBDesignable class CustomTextField : UITextField {

  @IBInspectable var borderColor: UIColor = UIColor.clearColor() {
    didSet {
      layer.borderColor = borderColor.CGColor
    }
  }

}

@IBDesignable class CustomView : UIView {

  @IBInspectable var borderColor: UIColor = UIColor.clearColor() {
    didSet {
      layer.borderColor = borderColor.CGColor
    }
  }

}

@IBDesignable class CustomButton : UIButton {

  @IBInspectable var borderColor: UIColor = UIColor.clearColor() {
    didSet {
      layer.borderColor = borderColor.CGColor
    }
  }

}

所有三个类都有相同的计算属性(borderColor)。 我想成为 DRY(不要重复自己)并从某处继承此类重复的计算属性或方法。有没有办法做到这一点?

我知道有一种方法可以通过协议扩展和协议方法的默认实现来做到这一点 - 但它看起来并不那么干净:

Calling protocol default implementation from regular method

【问题讨论】:

标签: swift


【解决方案1】:

我想这可以工作,虽然 IMO 并不完美:

protocol BorderColorView {
    var borderColor: UIColor! { get set }
}

extension BorderColorView {
    var borderColor: UIColor! {
        get {
            if let color = (self as? UIView)?.layer.borderColor {
                return UIColor(CGColor: color)
            }
            return nil
        }
        set {
            (self as? UIView)?.layer.borderColor = newValue.CGColor
        }
    }
}

//Example usage:

class MyView: UIView, BorderColorView { }

这样做的一个缺点是您只能在UIView 中遵守此协议,而不能在其他类中遵守此协议。

或者,您可以这样做:

protocol BorderColorView {
    var view: UIView { get }
    var borderColor: UIColor! { get set }
}

extension BorderColorView {
    var borderColor: UIColor! {
        get {
            if let color = (self as? UIView)?.layer.borderColor {
                return UIColor(CGColor: color)
            }
            return nil
        }
        set {
            (self as? UIView)?.layer.borderColor = newValue.CGColor
        }
    }
}

// Example usage:

class MyView: UIView, BorderColorView {
    var view: UIView {
        return self
    }
}

你看,这将创建一个重复代码。没有你的问题那么多,但它仍然是重复的代码。明智地选择你想要的onw。

【讨论】:

  • 感谢您的努力,但您的代码无法编译。
  • @etayluz 真的吗?我在操场上试过!您是否使用了编辑前的代码?那是错误的。请使用版本号 2 中的代码。
  • 我看到类型“MyView”不符合协议“BorderColorView”。运行 XCode 7.3.1
  • @etayluz 是的,这正是您使用旧代码时遇到的错误。现在复制答案中的代码,然后再试一次
  • @etayluz 不幸的是,没有。 @IBInspectable 只能应用于实例属性。对不起。
【解决方案2】:

你为什么不为 UIView 写一个扩展,你将能够在每个 UI 元素中使用它

【讨论】:

  • 因为 @IBDesignable 不适用于扩展 - 仅适用于子类
猜你喜欢
  • 1970-01-01
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-08
  • 2013-03-05
  • 1970-01-01
相关资源
最近更新 更多