某些UIControl的协议一致性扩展

时间:2017-02-21 10:37:39

标签: ios swift protocols

以下是我的案例:

我希望2个或更多UIControl符合通用协议:例如UISliderUIStepperMyCustomControl。这就是他们所拥有的:

class UIStepper {
  var value: Float
}

class UISlider {
  var value: Double
}

class MyCustomControl {
  var value: Int
}

现在,我喜欢类似于这样的协议:

protocol Valuable {
  associatedtype T
  var value: T
}

然后可以使用[Valuable]。但当然我遇到了着名的PATs问题

  

协议Valuable只能用作通用约束,因为它   有自我或相关的类型要求

我见过type erasure的方法和类似的在线方法。但我觉得我正在努力做的事情有些混乱。我希望能够拥有一个具有value属性的Controls数组,并且此属性只能是基本类型。当然,我可以继续创建多个数组,例如[IntValuable][DoubleValuable][FloatValuable]来绕过它。或者也许在某处某处使用NSNumber。或带有相关值的枚举。或者也许有一些我没有看到的东西,因此我在这里发帖:)我很感激一点指导!感谢。

2 个答案:

答案 0 :(得分:1)

我的问题不清楚你的需求是什么。怎么样:

enum Numeric {
    case int(Int)
    case double(Double)
    case float(Float)

    init(_ int: Int) {
        self = .int(int)
    }

    init(_ double: Double) {
        self = .double(double)
    }

    init(_ float: Float) {
        self = .float(float)
    }        
}

protocol Valuable {
    var numericValue: Numeric { get set }
}

extension UISlider: Valuable {
    var numericValue: Numeric {
        get { return .double(value) }
        set { value = newValue.value }
    }
}

等等,对于其他控件。然后,分配:

let slider: UISlider()
slider.numericValue = Numeric(3.14159)

答案 1 :(得分:0)

我最终做的方式如下:

protocol Valuable {
    func set(value: NSNumber)
}

extension UIStepper: Valuable {
    func set(value: NSNumber) {
        self.value = value.doubleValue
    }
}

extension UISlider: Valuable {
    func set(value: NSNumber) {
        self.value = value.floatValue
    }
}

然后我可以这样做:

var valuables: [Valuable] = [UISlider(), UIStepper()]

for valuable in valuables {
    valuable.set(value: 5)
}

通过这种方式,我可以轻松地为任何类添加更多扩展,即使其中的变量未命名为value