To provide more context: a screen in my app has a table, some table cells have switches in them (UISwitch).
I want to give each switch a target the moment it is created, like so:
cell.switch.addTarget(self, action: #selector({// do stuff }), for: .valueChanged)
And I want the function to be made into a selector to be inline, since it should be slightly different (changing a different value in an array) depending on the number of the row in which the switch has been flipped.
The problem is - the block above does not compile because the closure is not exposed to objective-C. Can i somehow expose it in the same line?
I do know about the option to tag my switches and make a shared called function for them, which behaves differently depending on the tag, like this:
cell.switch.tag = switchNumber
cell.switch.addTarget(self, action: #selector(switchFlipped), for: .valueChanged)
@objc func switchFlipped(sender: UISwitch){
let switchNumber = sender.tag
switch(tag){
// do stuff depending on the case
}
}
But I feel like possibly making an inline closure is quicker. Am I wrong?
In short, no, you can't pass a Swift closure to the
addTarget/selectorAPI fromUIControl.What you should be doing is hiding all of these details in the implementation of your custom table view cell class. Your
cellForRowAtdata source method should not even know that the cell has a switch.Your custom cell class should make itself the handler of the switch's
valueChangedaction. Your custom cell class should provide a callback closure property that it calls when the switch's value changes. In yourcellForRowAtyou can assign a closure to this property.This setup keeps the details of the cell's features where they belong - in the cell class. This also makes your implementation of
cellForRowAtmuch cleaner and it allows you to use a closure to handle whatever events your custom cell may trigger.Here's a rough example for the custom cell class:
And your
cellForRowAt:Adjust the details as needed for your setup.