1

First, let me state that I am not looking for a solution that is stated here. This one solves it using inheritance, but I cannot use that, as my needs are to have a composition solution.

I basically want to send more parameters when doing addTarget to a UIControl, using composition. I actually already have something working, but I am not sure at all if it's good practice, what are the drawbacks, and if there is another solution that is simpler. I'm hoping you can help me with that. Here is the solution. I basically wrap the control in a class that takes in the extra params and a closure that is called when the value changes.

class ControlWithParameters {
    var control: UIControl
    var extraParam: String
    var valueChanged: (UIControl, String) -> ()

    required init(_ control: UIControl, _ extraParam: String, _ valueChanged: @escaping (UIControl, String) -> ()) {
        self.control = control
        self.extraParam = extraParam
        self.valueChanged = valueChanged
        control.addTarget(self, action: #selector(valueChanged(sender:)), for: .valueChanged)
    }

    @objc internal func valueChanged(sender: UIControl) {
        self.valueChanged(sender, self.extraParam)
    }
}

let slider = UISlider()
let extraParam = "extraParam"
let controlWithParameters = ControlWithParameters(slider, extraParam, valueChanged)

func valueChanged(_ control:UIControl, _ extraParam: String) {
    print(extraParam)
}

Is this a good solution? I can't know if this memory efficient or not, and I don't know if I'm complicating myself for this simple task. Any help is appreciated!

Community
  • 1
  • 1
Guy Daher
  • 5,526
  • 5
  • 42
  • 67
  • Well, Im also doing this for my custom closure button, the only thing need to take cares is that you have to use `[weak self]` if you capture `self` in the closure, else it will create retain loop, also not sure why you need to pass back the string, you want to modify it when using? – Tj3n Feb 28 '17 at 11:42
  • @Tj3n I'm passing it back since I need to use it on my main class when the value change. And good point for [weak self], but where can I put it since I don't really have a "real" closure declaration? Do I just declare `weak var weakSelf = self` and then use it inside `@objc internal func valueChanged(sender: UIControl)`? – Guy Daher Feb 28 '17 at 12:40
  • You only put it when you create the UIControl on your other class and refer to `self` that is the other class, when you create it you should also declare what you want to do in the closure, thats when you use `[weak self] in..` – Tj3n Mar 01 '17 at 02:47

0 Answers0