第7回 ノブをドラッグ(パン)で移動できるようにする | SwiftUIでカラーピッカーを作る

SwiftUIでカラーピッカーを作るという連載です。今回はノブをドラッグ(パン)ジェスチャーで移動できるようにする処理を実装します。

目次

SwiftUIではDragGestureを使う

UIKitではiOSやiPadOSで、スクリーンを指でなぞるジェスチャーのことを「パン」と呼びます。macOSではマウスやトラックパッドを使って行う同様の操作は「ドラッグ」と呼んでいます。

SwiftUIはiOS, iPadOS, macOSのいずれにも対応しているので「ドラッグジェスチャー」と呼んでいます。

DragGestureの使い方

SwiftUIでドラッグジェスチャーを使うには、ジェスチャーを使いたいビューのgesture()モディファイアにDragGestureを渡します。

var drag: some Gesture {
    DragGesture()
        .onChanged { dragValue in
            // ドラッグ中の処理
        }
        .onEnded { dragValue in
            // ドラッグ完了時の処理
        }
}

var body: some View {
        SomeView() // ジェスチャーを使うビュー
            .gesture(drag)
}

ノブの移動処理の実装

ドラッグジェスチャーでノブを移動する処理を実装します。まずは、ドラッグジェスチャーの処理の実装です。

dragプロパティの実装

実装する処理はタップと同様に、ジェスチャーの発生している座標のX座標の値から現在値を計算して、ColorPickerChannelModel.currentValueプロパティの値を更新します。

PickerGradationViewに次のようなコードを追加します。

struct PickerGradationView: View {
    
    var drag: some Gesture {
        DragGesture()
            .onChanged { dragValue in
                channel.changeCurrentValue(dragValue.location.x / gradation.viewSize.width)
                channel.clearFieldText()
            }
    }

ビューへのジェスチャーの設定

dragプロパティで取得したジェスチャーをビューに設定します。ビューへの設定はgesture()モディファイアを使用します。次のようなコードになります。

struct PickerGradationView: View {
    
    var body: some View {
        ZStack(alignment: .leading) {
            GeometryReader() { geometry in
                LinearGradient(gradient: Gradient(colors: [gradation.startColor, gradation.endColor]), startPoint: UnitPoint(x: 0, y: 0), endPoint: UnitPoint(x: 1, y: 0))
            }
            .frame(height: gradationHeigh)
            .background {
                GeometryReader { geometry in
                    Path { path in
                        Task.detached {
                            await updateViewSize(geometry.size)
                        }
                    }
                }
            }
            .onTapGesture { point in
                channel.currentValue = point.x / gradation.viewSize.width
                channel.clearFieldText()
            }
            .gesture(drag)

動作確認

動作確認します。ColorPicker.swiftを開いてライブプレビューでグラデーションビュー上をドラッグします。ドラッグしたカーソルの位置にノブが移動して、テキストフィールドにも新しい現在値が表示されます。

Xcodeのライブプレビューで動作確認

コードのダウンロード

今回の記事で作成したコードのダウンロードはこちらです。

連載目次

著書紹介

Authored Books

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

目次