How can we implement 3D touch to check if the user taps on UIView
or force touch on UIView
?
Is there a way to do this with UIGestureRecognize
or only with UITouch
?
How can we implement 3D touch to check if the user taps on UIView
or force touch on UIView
?
Is there a way to do this with UIGestureRecognize
or only with UITouch
?
The way I am doing this is to use a combination of a UITapGestureRecognizer (provided by Apple) and a DFContinuousForceTouchGestureRecognizer (provided by me).
The
DFContinuousForceTouchGestureRecognizer
is nice because it provides continuous updates about the pressure changes so you can do things like augment the view as the user varies their pressure on it, as opposed to a single event. If you just want a single event you can ignore eveything in theDFContinuousForceTouchDelegate
except the- (void) forceTouchRecognized
callback.https://github.com/foggzilla/DFContinuousForceTouchGestureRecognizer
You can download this and run the sample app on a device that supports force press to see how it feels.
In your
UIViewController
implement the following:implement selector for tap gesture
Implement the delegate protocol for force touch:
Note that this will only be useful on a device that supports force touch.
Also you should not add the
DFContinuousForceTouchGestureRecognizer
to a view if are you running on iOS 8 or under since it uses the newforce
property onUITouch
only available in iOS 9.If you add this on iOS 8 it will crash, so conditionally add this recognizer based on what iOS version you are running on if you are supporting versions older than iOS 9.
With Swift 4.2 and iOS 12, a possible way to solve your problem is to create a custom subclass of
UIGestureRecognizer
that handles Force Touch and add it to your view next to aUITapGestureRecognizer
. The following complete code shows how to implement it:ViewController.swift
ForceTouchGestureRecognizer.swift
Sources:
GitHub / FlexMonkey - DeepPressGestureRecognizer
GitHub / ashleymills - ForceTouchGestureRecognizer
Apple Developer Documentation - Implementing a Discrete Gesture Recognizer
I created a UIGestureRecognizer that emulates the behavior of the Apple Mail app. Upon 3D touch, it starts with a short single pulse vibrate and then an optional secondary action (hardTarget) and pulse called by hard pressing shortly after the initial press.
Adapted from https://github.com/FlexMonkey/DeepPressGestureRecognizer
Changes:
Note: I added the undocumented system sound k_PeakSoundID, but feel free to turn that off if you are uncomfortable using a constant beyond the documented range. I have been using system sounds with undisclosed constants for years, but you are welcomed to turn off the vibration pulses using the vibrateOnDeepPress property.
The 3D Touch properties are available on
UITouch
objects.You can get these touches by overriding a
UIView
'stouchesBegan:
andtouchesMoved:
methods. Not sure what you see intouchesEnded:
yet.If you're willing to create new gesture recognizers, you have full access to the
UITouch
es as exposed inUIGestureRecognizerSubclass
.I'm not sure how you could use the 3D touch properties in a traditional
UIGestureRecognizer
. Maybe via theUIGestureRecognizerDelegate
protocol'sgestureRecognizer:shouldReceiveTouch:
method.You can do it without a designated gesture recognizer. You do not need to adjust the touchesEnded and touchesBegan method, but simply the touchesMoved to obtain the correct values. getting the force of a uitouch from began/ended will return weird values.
then, set a force threshold and compare the normalizedForce to this threshold (0.75 seems fine for me).