我想创建UISlider的扩展名,该扩展名允许我在滑块值更改后使用回调函数来执行操作。换句话说,与使用UIControl.Event.valueChanged添加操作具有相同的效果。
所以不要添加这样的动作:
let mySlider = UISlider()
mySlider.addTarget(self, action: #selector(sliderDidChangeValue(_:)), for: .valueChanged)
@objc func sliderDidChangeValue(_ sender: UISlider) {
print(sender.value)
}
我想创建一个这样的扩展,但是其中一个回调的行为与上面的操作相同:
extension UISlider {
convenience init(value: Float = 0,
range: ClosedRange<Float> = 0 ... 1,
callback: @escaping (_ x: Float) -> Void = { _ in}) {
self.init()
self.value = value
self.minimumValue = range.lowerBound
self.maximumValue = range.upperBound
}
}
let mySlider = UISlider(value: 10, range: 1...10) { (newValue) in
print(newValue)
}
在我看来,应该可以实现,但是我真的不确定如何去实现它。预先感谢您的帮助。
如果要将闭包作为目标添加到UISlider
,则必须使用扩展名将函数添加到UISlider
。
@objc class SliderClass: NSObject {
let closure: (_ val:Float)->()
init (_ closure: @escaping (_ val:Float)->()) {
self.closure = closure
}
@objc func invoke (sender:UISlider) {
closure(sender.value)
}
}
extension UISlider {
func addAction(for controlEvents: UIControl.Event = .valueChanged, value : Float = 1, range : ClosedRange<Float> = 0 ... 1, _ closure: @escaping (_ val:Float)->()) {
self.minimumValue = range.lowerBound
self.maximumValue = range.upperBound
self.value = value
let classObj = SliderClass(closure)
addTarget(classObj, action: #selector(SliderClass.invoke), for: controlEvents)
objc_setAssociatedObject(self, "", classObj, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
在课堂上使用
slider.addAction(value:1.9,range: 0 ... 2) { (newValue) in
print(String(format: "%.2f", newValue))
}
OR
slider.addAction(value:1.5, range: 0 ... 2) {
print(String(format: "%.2f", $0))
}