Gestures in SwiftUI at scale
iOS SwiftUI Gestures Estimated reading time: 9 minutesTouch interface provides users essential way to communicate with a device with phenomenal simplicity. U even can’t notice how many gestures u did in the last few hours while u use your phone. But if u think about it - the number of gestures interactions may surprise you.
Thinking about better usability for our apps, we should also remember about Gesture
functionality. With SwiftUI
gestures API becomes even more powerful and simple in comparison to UIKit
.
About gesture
We can apply gestures using few approaches in SwiftUI
. One requires from us only use specially designed function for handling main aspect of any gesture (for example action from TapGesture
can be handled with onTapGesture(count:perform:)
, or LongPressGesture
can be handled with onLongPressGesture(minimumDuration:pressing:perform:)
).
Another one - use gesture modifier that can apply any gesture type to view with all needed events in it.
Actually there are few modifies -
gesture(_:including:)
,highPriorityGesture(_:including:)
andsimultaneousGesture(_:including:)
.These names already provide a partial answer about the purpose of each function.
From the documentation we can find, that Gesture
in SwiftUI
- * its stream of values for state-provided from the sequence of the event.* This type is defined as a protocol and requires to provide a type of Value
that will be returned with gesture and body
- content and behavior of the gesture.
Before we review any type of Gesture
, it’s good to know what can be done within it and which event’s can be handled/received.
Gesture protocol has few extension function that provide functionality for performing gestures related operations:
So, these are the main 3 activities that are interesting for us. But if we think a bit, then we may realize that for example TapGesture
don’t need the onChanged(_:)
function, thus tap its just a tap, and such an event as change simply can’t exist for it (or will never provide useful information).
Keeping this in mind, Apple has defined Value
for the gesture, which can interpret the possibility of changes. Modifier as onChanged(_:)
can’t be executed for values that can’t change and if we back to TapGesture
there is no such value - when we check documentation we can find:
this mean that onChanged(_:)
is not applicable bacause Value
is not Equatable
(onChanged(_:)
has requirement that Self.Value : Equatable
) - nothing can’t cnange.
It’s good to know that for a gesture that can have an end event there is a type
_EndedGesture<T>
(A gesture that triggers
actionwhen the gesture ends
), for one that can have change in some state -_ChangedGesture<T>
(A gesture that triggersaction
when this gesture’s value changed), for those of them who can update some value based on state -GestureStateGesture<T, V>
.Prefix
_
on some types means that this is a private type, so realization details are hidden from us, but we can make an assumption about functionality behind.
Gesture types
Sometimes a picture is better than a thousand words. So here are available gestures in SwiftUI
TapGesture
I already mention TapGesture
- this is one of the simplest gesture.
We already discovered that Value
for this gesture is Void
and body
can’t be changed.
We may use this gesture in a few ways:
Tap gesture also has
count
parameter, by default equal to 1, so if needed u may specify any numbers of tap, beforeTapGesture
fire end event
or
note - we may also use an updating function on tap gesture, but its gonna never be called because
Value
isVoid
LongPressGesture
This gesture according to its name used for detecting longPress events - no surprise here ;].
In comparison to tap, updating is now can be used, because it has defined value type as public typealias Value = Bool
. This mean, that additional function onChanged(_:)
also available (Bool
is Equatable
). Lets see it in action:
I wrote separate article about
propertyWrappers in SwiftUI
Result:
And don’t forget about simplified version for long press action:
DragGesture
A gesture that allows very common operation such as drag, on in other words - swipe.
Value
for this gesture is quite interesting, contains a lot of data and defined as next:
As u can see - we can use a lot of data from the Value
type and so perform the same complex operation as with old gestures in UIKit
. Commonly used translation
value, thus in most cases, we only need an amount of moved distance over screen:
Result:
Check simplified API on your own - it’s very similar to previously shown here.
For the next gestures I won’t write any information about this option and let u experiment with it on your own.
RotationGesture
Another one gesture on the list - RotationGesture
. The purpose is pretty clear from the name - we can perform scale using 2 fingers on the screen and move them in a circular motion in the same direction.
Value
for this gesture defined as next:
Angle
can be used to any transformation, for example:
Result:
MagnificationGesture
This is a new name for pinch and zoom gesture. To invoke it - use 2 fingers towards each other or away to zoom out or in.
Value
for this gesture defined as next:
We can experiment with this gesture using next snipet:
As result u can receive something like:
HoverGesture
This gesture available for macOS/iPadOS, but we also may define it in iOS - the effect will be not visible.
on macOS in
UIKit
for the same effect may be usedUIHoverGestureRecognizer
Trigger for this gesture - pointer over the object. Various howerEffect may highlight view element on pointer enter event.
To simulate on simulator we can use iPad, and use SimulatorMenu -> I/O -> Input -> Send pointer to device
Combination of gestures
This is a very powerful feature of gestures that simplify usage of different gestures and so allow us to provide to user special interaction gestures, making unique feelings about any app.
The combination may be used in a few ways: by modifying the sequence of gestures or by specifying priorities of them in the view tree, or by configuring them to use simultaneously. To do so Apple included in SwiftUI a full set of tools:
We may grab some of this and create next sample:
Result:
Good sample of the composition of gesture available here
Conclusion
SwiftUI
not only save for us all options available from UIKit
in terms of gestures but also introduce a few new options within great simplification.
Share on: