Updated 28 January 2019
If you’ve ever used an iOS device, then, whether you know it or not, you’ve used tap gesture recognition on many occasions. like double tapping functionality, add action to non-clickable view objects etc. All of these actions are done by tap gesture recognizers.
The worst part about adding a UITapGestureRecognizer
 or any sort of gesture recognizer/target action is implementing a new function solely for the selector parameter. For this, I’d like to share a neat trick I threw together that lets you add gesture recognizers without selectors.
Let’s say we have anUIImageView
 in our View Controller and we want to add a UITapGestureRecognizer
 to it that prints out a statement whenever it’s tapped.
Normally we would create an instance of a UITapGestureRecognizer
 and set a target to the View Controller and its selector as some function we quickly threw together (myImageViewTapped(sender: UITapGestureRecognizer)
). This can get a bit redundant and can lead to messy code with functions for every subview you want to add interactivity too.
I got to thinking that I could just make a quick extension that adds tap gesture recognizers to my image view for me, but then I’d have to make a new function for each recognizer, right? Wrong! Using the power of associated objects, we can actually store closures as computed properties in our extension!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
extension UIView { fileprivate struct AssociatedObjectKeys { static var tapGestureRecognizer = "MyAssociatedObjectKeyForTapGesture" } fileprivate typealias Action = (() -> Void)? fileprivate var tapGestureRecognizerAction: Action? { set { if let newValue = newValue { objc_setAssociatedObject(self, &AssociatedObjectKeys.tapGestureRecognizer, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } } get { let tapGestureRecognizerActionInstance = objc_getAssociatedObject(self, &AssociatedObjectKeys.tapGestureRecognizer) as? Action return tapGestureRecognizerActionInstance } } public func addTapGestureRecognizer(action: (() -> Void)?) { self.isUserInteractionEnabled = true self.tapGestureRecognizerAction = action let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture)) self.addGestureRecognizer(tapGestureRecognizer) } @objc fileprivate func handleTapGesture(sender: UITapGestureRecognizer) { if let action = self.tapGestureRecognizerAction { action?() } else { print("no action") } } } |
1 2 3 4 5 6 7 |
override func viewDidLoad() { super.viewDidLoad() myImageView.addTapGestureRecognizer { print("Image tapped") } } |
Thank You!!!
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.