[SwiftUI]Image上でTextをドラッグして動かす(DragGesture使用)

画面に表示されているイメージ上に、ドラッグでアイテムを配置したいので、そのための技術要素を説明します。




ゴール:Imageの上にTextを表示して、そのTextをマウスドラッグで移動させたい

以下のようなステップで作っていきます。
・イメージを表示
・テキストをイメージに重ねて表示
・テキストをドラッグ可能に
・ドラッグされた時にテキストを移動

Step0: Imageを表示

表示する写真

例えば、このような写真を表示する。
View

Assets.xcassetsに登録

表示するためには、プロジェクトのリソースに登録しておくと簡単にできます。

ということで、Assets.xcassetsにドラッグアンドドロップして登録します。

submit to asset

使ったファイルは、JPGファイルなので、ファイル名は、View.jpgです。

Imageビューの引数にファイルを指定して表示するようにします。

Imageの表示

こんな感じになります。

Image only

Step1: ImageとTextを重ねて表示

目標は、Image上にTextを配置して、そのTextをマウスドラッグで動かすことなので、そのためのTextを配置します。

確認しやすいように、背景を白にしてTextを配置します。

Imageの上にTextを表示

Hello World!がイメージ上に表示されているのが確認できます。

Image with text




Step2: Textのドラッグ対応

SwiftUIでは、.gesture modifierで受けます。
全般については、ここを。

今回は、ドラッグでの操作を行いたいので、使用するクラスは、DragGestureになります。DragGestureについては、こちらを。

ざっくりいうと、ドラッグ中とドラッグ終了時に指定Closureが実行されます。
まずは、どんな感じになるか確認するために、簡単なprint文を埋め込んだコードにしてみます。

TextにGesture追加

ドラッグ中、ドラッグ終了時いずれも、DragGesture.ValueがClosureに渡されます。その情報から、現在の位置や移動距離を取得することができます。
ここでは、ドラッグ中の移動距離(.translation)をprintしています。
アプリとして動かしてみると、以下のようにコンソールに表示されることを確認できるかと思います。

ちなみに、上下左右に動かしてみると表示される+/ーが切り替わっていきますので、X軸Y軸のどちら側がプラスでどちら側がマイナスかがわかります。普通の数学でならうものと比較するとY軸方向が逆(上方向がマイナス、下方向がプラス)になっているのがわかるかと思います。

Step3: Textのoffset表示

テキストをどうやって動かすかですが、Textの表示位置をoffsetさせることで実現することにします。.offset modiferというものが用意されています。どのような意味を持つか使ってみましょう。

@State修飾子がついた変数として、textOffsetを定義し、その値を.offset modifierでテキストに適用しています。

.offsetを確認するコード

以下のようになり、offset指定することでTextの位置が動かされていることがわかります。

offset text

Step4: offsetを使ってドラッグで移動

このtextOffset変数とDragGesture時に取れるtranslationを紐づけることで、Textを移動できそうです。

@State変数とGesture引数の紐付け

注意
.offsetは、表示位置だけ変更するmodifierなので、最初からオフセットされた状態にしてしまうと、DragGestureから渡される値との動きがおかしくなってしまいますので、textOffsetは、CGSize.zeroに設定変更しています。




Step5: まとめ

Image上に表示したテキストについて、
・ .gestureを使って、マウスの移動量を取得、
・ .offsetを使って、Textの表示位置を調整
しました。

@State変数は、ドラッグ終了後も値を保持していますので、ドラッグ後にテキストの位置を知りたい等で参照することもできます。

MEMO
画面スナップショットは、MacOSアプリとして動かしたものを使っていますが、特にMacOS限定機能は使っていません。




コメントを残す

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