[SwiftUI] ドラッグによりViewを移動させるときに気をつけること

先日の [SwiftUI]Image上でTextをドラッグして動かす でImage上のTextをドラッグして動かす方法を説明したのですが、実は、以下の問題点があります。

  • ドラッグし終わったときのPositionを参照しないので、2回目以降のドラッグ開始時にTextが急激に移動する

問題の発生原因

この問題(2回目以降のドラッグ開始時にTextが急激に移動する)は、サンプルのDrag処理では、Textのoffsetはドラッグ開始時には(0,0)であることを想定して書かれているので、offsetが(0,0)で無い位置にあるときにドラッグを開始すると、offsetが(0,0)の位置にあったこと前提で移動処理をします。そのため、ドラッグ開始時にTextが急激に移動しているように見えます。

図にすると以下のような形です。

MouseDragとText移動

ドラッグ時にズレが発生しないための方法

以下のことが必要です。

  • ドラッグ開始時にどこにTextがあったか覚えておく
  • 移動させるときには、ドラッグ開始時の位置からの相対位置で移動させる

ドラッグ開始時のText位置と移動計算

onChangeは、ドラッグ開始時にも呼ばれますので、ドラッグ開始時に、自Viewの中に、Textのoffsetを保持します。(dragStartPosition)

移動継続中にもonChangeは呼ばれますので、開始時のみTextのoffsetを保持するような変数も導入します。(isDragging)

移動中のoffsetの計算も、ドラッグ開始時の位置情報とtranslation情報を使って、新しいoffsetを計算します。

コードにすると、以下のようになります。

コード

まとめ

細かい処理追加ですが、上記の処理を追加することで、直感的なドラッグ処理になります。

MEMO
上記のようなコードを書いていると、CGRectやCGPoint等を変換しつつ計算してくれるライブラリが欲しくなります。

1 COMMENT

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です