How to apply iOS 3D Touch to any UIView as a UIGestureRecognizer
I know, rumors are reporting Apple to remove 3D Touch in 2019 new devices, but I’m still in love with this feature since it’s first implementation in iPhone 6s.
As a developer I’ve only implemented it in UITableView cells, UICollectionView cells with peek and pop and in Quick Actions in iOS SpringBoard, but recently I needed to have an UIGestureRecognizer to apply to any UIView that intercepts 3D Touch as you can do with tap, drag, ecc, but nothing similar is available in system libraries.
As result of my study about this implementation, I’ve written a UIGestureRecognizer subclass that can fit my needs.
First step is to import in the swift file the right library and create your empty UIGestureRecognizer subclass overriding four methods you’ll need for the implementation:
Now we are ready for start writing main methods and istance variables to handle force touch:
deepPressed is keeping memory if the force touch has been executed
threshold is the minimum percentage of force touch to trigger the gesture.
deepPressedAt and hardTriggerMinTime which represents respectively the timestamp of the first force touch and minimum time in force touch to handle the gesture.
The two methods implements the logic that valorize those variables and that change gesture state.
I’m keeping memory of the status using deepPressed boolean variable, because I set gesture state to .began when passing threshold, than .end if 100% of 3D Touch depth is reached, .cancelled otherwise.
I could have use and intermediate status like .possible or .changed but this way is more explicit and cleaner in the deepPressed didSet. Using state changes would have led me to a long switch statement on gesture status changes and i prefer to split logics without hard use of superclass.
Now let’s add a tuple for target and action and a custom init:
super.init() is passing nil to both parameters because we don’t need to use anything from superclass.
Next step is to integrate handleTouch method in iOS UIGestureRecognizer default methods and use State changes for action invocation handling:
Now our little UIGestureRecognizer is complete, and we can assemble all previous snippets. The result will be something like this:
If you need to implement 3D Touch in your project and you prefer to use a tested and maintained external component, my class is available via CocoaPods. In my open-source project is also implemented the haptic feedback on gesture success so you can explore how to use it.
You can find it on GitHub: https://github.com/neobeppe/GTForceTouchGestureRecognizer
Or on CocoaPods: https://cocoapods.org/pods/GTForceTouchGestureRecognizer