我如何扩展UISlider,以便它使用一个回调来检测滑块值何时更改?

问题描述 投票:0回答:1

我想创建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)
}

在我看来,应该可以实现,但是我真的不确定如何去实现它。预先感谢您的帮助。

swift uikit extension-methods uislider subclassing
1个回答
0
投票

如果要将闭包作为目标添加到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))
}
© www.soinside.com 2019 - 2024. All rights reserved.