SwiftUI

[SwiftUI]オブジェクトのドラッグを可能にし、移動した座標を表示する. How to drag an object and display its position in SwiftUI.

SwiftUI

Xcode: 12.4, Swift: 5

SwiftUIのViewにおいて、作成したオブジェクトをドラッグし、そのドラッグ後の座標をリアルタイムに表示する方法を紹介します。ポイントとなるキーワードは以下のとおりです。

  • @State
  • .gesture
  • onChanged

1. オブジェクトを作成(ここではCircle)

[ads]
import SwiftUI

struct Sample: View {
    var body: some View {
        Circle()
            .fill(Color.blue)
            .frame(width: 80, height: 80)
    }
}
インプリした青の80*80のサークルオブジェクトが表示される。
特に指定していないため、画面中央に表示される。

2. @State変数を追加

[ads]
import SwiftUI

struct Sample: View {

    @State private var location: CGPoint = CGPoint(x: 0, y: 0)

    var body: some View {
        VStack {
            Circle()
                .fill(Color.blue)
                .frame(width: 80, height: 80)
                .position(location)
        }
    }
}

.positionモディファイアを使用し、@State変数にバインディングすることで、この@State変数であるlocationの変化にサークルオブジェクトが追従するようになります。

3. 座標表示用のテキストボックス追加

[ads]
import SwiftUI

struct Sample: View {

    @State private var location: CGPoint = CGPoint(x: 0, y: 0)

    var body: some View {
        VStack {
            Text("x: \(location.x)")
            Text("y: \(location.y)")
            Circle()
                .fill(Color.blue)
                .frame(width: 80, height: 80)
                .position(location)

        }
    }
}

座標表示用のテキストボックスを追加。
VStackで追加しているため、サークルの座標は(0, 0)のままだが、テキストボックスの分下方向にずれています。

4. gestureモディファイアを追加

[ads]

.gestureを追加することで、ジェスチャーを認識することができる。その一つである、onChangedイベントを利用する。Closureを用いて、このサークルオブジェクトのpositionモディファイアにバインディングされているlocation変数を、現在の座標で都度更新するような動作。

import SwiftUI

struct Sample: View {

    @State private var location: CGPoint = CGPoint(x: 0, y: 0)

    var body: some View {
        VStack {
            Text("x: \(location.x)")
            Text("y: \(location.y)")
            Circle()
                .fill(Color.blue)
                .frame(width: 80, height: 80)
                .position(location)
                .gesture(DragGesture().onChanged({ value in self.location = value.location}))
        }
    }
}

Live Previewにすることで、ドラッグイベントの変化が@State変数のlocationにリアルタイムに更新され、その値が同時にリアルタイムにテキストボックスに表示されるようになります

すこし動かした状態
ドラッグに追従して座標が変化していることがわかります
Ads