View をドラッグして動かします。
struct TestDragGesture: View {
@State private var location = CGPoint(x: 150, y: 150)
var body: some View {
ZStack {
VStack(alignment: .trailing) {
Text("location.x: \(location.x)")
Text("location.y: \(location.y)")
}
.monospaced()
Circle()
.fill(.red.opacity(0.5))
.frame(width: 100)
.position(location)
.gesture(
DragGesture()
.onChanged { value in
location = value.location
}
)
}
}
}
ドラッグ位置が変化するたびに View の位置を更新できます。
var location: CGPoint
The location of the drag gesture’s current event.
👉 DragGesture.Value | Apple Developer Documentation
Circle の position は Viewの中心
であることに対して
DragGesture().onChanged() で取得したドラッグ位置
とずれがあるため、
タップ位置を動かした瞬間に中心位置にジャンプしてしまいます。
なんか違和感がありますね !
👩🏼💻 startLocation と translation
計算方法を変えます。
以下を使います。
var startLocation: CGPoint
The location of the drag gesture’s first event.
var translation: CGSize
The total translation from the start of the drag gesture to the current event of the drag gesture.
👉 DragGesture.Value | Apple Developer Documentation
Circle()
.fill(.red.opacity(0.5))
.frame(width: 100)
.position(location)
.gesture(
DragGesture()
.onChanged { value in
var newLocation = startLocation ?? location
newLocation.x += value.translation.width
newLocation.y += value.translation.height
location = newLocation
}
.updating($startLocation) { _, startLocation, _ in
startLocation = startLocation ?? location
}
)
Circle の中心位置に対して、ドラッグの移動量を増減することで、なめらかに違和感なく動くようになりました !
簡単なコードに見えますが、updating を使った位置情報の入れ替えとか、よくみると深い。
👉 updating(_:body:) | Apple Developer Documentation
👉 Move your view around with Drag Gesture in SwiftUI | Sarunw
しかし、なんか見通しが悪い。
@GestureState と updating() は使いづらい。
👩🏼💻 まとめ
これでいきます。
キモは、
と
【SwiftUI】Create Draggable Reorder ListView without List #プログラミング #エンジニアhttps://t.co/4CYemmy7oF
— chanzmao (@maochanz) September 13, 2024