Created
May 1, 2019 14:32
-
-
Save koingdev/616fc27cd3d7e37e2a7186a4eca7fb52 to your computer and use it in GitHub Desktop.
Handle UIControl event closure-base instead of (target/action)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Handle UIControl event closure-base instead of (target/action) | |
Example: | |
```swift | |
// Button | |
button.on(.touchUpInside) { btn in | |
print("Button clicked") | |
} | |
// TextField | |
textField.on(.editingChanged) { tf in | |
print("Text changed") | |
} | |
``` | |
*/ | |
public protocol UIControlEventHandler: AnyObject { } | |
extension UIControl: UIControlEventHandler { } | |
// MARK: Associated Key | |
private struct AssociatedKeys { | |
static var EventHandlers = "_EventHandlers" | |
} | |
// MARK: Implementation | |
public extension UIControlEventHandler where Self: UIControl { | |
private var events: [UIControlEvent<Self>] { | |
get { | |
return (objc_getAssociatedObject(self, &AssociatedKeys.EventHandlers) as? [UIControlEvent<Self>]) ?? [] | |
} | |
set { | |
objc_setAssociatedObject(self, &AssociatedKeys.EventHandlers, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) | |
} | |
} | |
public func on(_ events: UIControl.Event, closure: @escaping (Self) -> Void) { | |
let handler = UIControlEvent<Self>(sender: self, events: events, closure: closure) | |
self.events.append(handler) | |
} | |
} | |
private final class UIControlEvent<Sender: UIControl>: NSObject { | |
let closure: (Sender) -> Void | |
init(sender: Sender, events: UIControl.Event, closure: @escaping (Sender) -> Void) { | |
self.closure = closure | |
super.init() | |
sender.addTarget(self, action: #selector(self.action), for: events) | |
} | |
@objc private func action(sender: UIControl) { | |
guard let sender = sender as? Sender else { return } | |
self.closure(sender) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment