Skip to content

Instantly share code, notes, and snippets.

@zahmedpk
Last active January 8, 2021 14:25
Show Gist options
  • Save zahmedpk/803b6a2ba8da0ead4cc54d82e2a9fec7 to your computer and use it in GitHub Desktop.
Save zahmedpk/803b6a2ba8da0ead4cc54d82e2a9fec7 to your computer and use it in GitHub Desktop.
Use multiple gestures to interact with an object.
// SwiftUI Gestures Tiny Example
// Xcode 12.3
// This gist shows how to use multiple gestures on same object.
// We draw a rectangle on screen that can be
// 1. pinch zoomed
// 2. rotated
// 3. tapped (single tap) to change opacity
// 4. tapped (double tap) to change color
// 5. long press to scale up (+0.2)
import SwiftUI
struct ContentView: View {
@State var translationXDuringDrag: CGFloat = 0.0
@State var translationYDuringDrag: CGFloat = 0.0
@State var translationXCumulative: CGFloat = 0.0
@State var translationYCumulative: CGFloat = 0.0
@State var transientZoomScale: CGFloat = 1.0
@State var steadyStateZoomScale: CGFloat = 1.0
@State var alpha: CGFloat = 0.3
@State var color: UIColor?
@State var transientRotation: Angle = Angle.init(degrees: 0)
@State var steadyStateRotation: Angle = Angle.init(degrees: 0)
let colors = [UIColor.blue, UIColor.systemPink, UIColor.yellow, UIColor.green]
var zoomScale: CGFloat {
transientZoomScale * steadyStateZoomScale
}
var rotation: Angle {
steadyStateRotation + transientRotation
}
var body: some View {
VStack {
Color(color == nil ? UIColor.blue.withAlphaComponent(alpha) : color!.withAlphaComponent(alpha))
.frame(width: 200, height: 200, alignment: .center)
.cornerRadius(10)
.scaleEffect(zoomScale)
.rotationEffect(rotation)
.transformEffect(.init(translationX: translationXCumulative+translationXDuringDrag, y: translationYCumulative+translationYDuringDrag))
.gesture(dragGesture)
.gesture(rotationAndMagnification)
.onTapGesture(count: 2) {
color = colors.filter {$0 != color}.randomElement()
}
.onTapGesture {
alpha += 0.2
if alpha > 0.8 {
alpha = 0.1
}
}
.onLongPressGesture {
withAnimation {
steadyStateZoomScale += 0.2
}
}
}
.background(Text(
"""
box can be
1. dragged
2. pinch zoomed/rotated.
3. Single tap to change alpha
4. Double tap changes color
5. Long press zooms up incrementally
"""
))
}
var dragGesture: some Gesture {
DragGesture()
.onChanged { (value) in
translationXDuringDrag = value.translation.width
translationYDuringDrag = value.translation.height
}
.onEnded { value in
translationXCumulative += value.translation.width
translationYCumulative += value.translation.height
translationXDuringDrag = 0
translationYDuringDrag = 0
}
}
var magnificationGesture: some Gesture {
MagnificationGesture()
.onChanged({ (value) in
transientZoomScale = value
})
.onEnded { (finalValue) in
transientZoomScale = 1
steadyStateZoomScale *= finalValue
}
}
var rotationGesture: some Gesture {
RotationGesture()
.onChanged { (angle) in
transientRotation = angle
}
.onEnded { (finalAngle) in
steadyStateRotation += finalAngle
transientRotation = Angle()
}
}
var rotationAndMagnification: some Gesture {
rotationGesture.simultaneously(with: magnificationGesture)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment