๐Drag
Last updated
Last updated
SwiftUI โฉ Gestures โฉ Drag โฉ
โฌ๏ธ ้่ฆ๏ผ Vector2D
๐ ๅ่๏ผMastering SwiftUI, Ch. 17: Using Gestures (p.374)
import SwiftUI
struct StarView: View {
// โญ๏ธ `@GestureState`: tracks gesture's state
// โข will reset to original value when gesture endsโ
// โข need another @State property to save final stateโ
typealias DragState = (offset: CGSize, isDragging: Bool)
@GestureState private var dragState: DragState = (.zero, false)
// โญ๏ธ save final drag state
@State private var viewOffset = CGSize.zero
// view body
var body: some View {
Image(systemName: "star.circle.fill")
.font(.system(size: 100))
.border(.secondary)
.overlay(overlay)
.offset(totalOffset) // โญ๏ธ apply offset
.foregroundColor(dragState.isDragging ? .pink : .yellow)
.gesture(drag) // โญ๏ธ drag gesture
}
/// โญ๏ธ drag gesture
var drag: some Gesture {
DragGesture()
// โญ๏ธ update @GestureState property
// โข value: DragGesture.Value (current drag gesture's value)
// โข state: @GestureState property
// โข transaction: Transaction (ignored)
.updating($dragState) { value, state, _ in
// โญ๏ธ update `dragState`
state.offset = value.translation
state.isDragging = true
}
.onEnded { value in
// โญ๏ธ when drag ends, `dragState` will reset.
// โญ๏ธ save final drag total translation to `viewOffset`
viewOffset += value.translation // ๐
ฟ๏ธ Vector2D
}
}
/// view's offset + drag's offset
var totalOffset: CGSize {
viewOffset + dragState.offset // ๐
ฟ๏ธ Vector2D
}
/// overlay text
var overlay: some View {
VStack(alignment: .leading) {
Text(verbatim: "drag: \(dragState.offset)")
.fixedSize()
Text(verbatim: "view: \(viewOffset)")
.fixedSize()
Text(verbatim: "drag + view: \(totalOffset)")
.fixedSize()
}
.foregroundColor(.secondary)
.offset(y: -110)
}
}
SwiftUI โฉ
Gestures โฉ
DragGesture (struct)
DragGesture.Value (struct)
translation (CGSize) - total translation of the drag.
location (CGPoint) - current location of the drag.
use GestureState to track gesture's state.