simultaneousGestureで複数同時にGestureを行う

Published by @SoNiceInfo at 6/24/2020


simultaneousGestureを利用しているXcode

simultaneousGestureでGestureをつなげる事により複数同時にGestureを行うことができます。
ここでは画像の拡大と回転を同時に行う例を紹介します。

画像の回転と拡大を同時に行う

RotationGestureで回転を取得して、MagnificationGestureで拡大・縮小を取得します。
simultaneousGestureを利用することで上記2つのGestureを同時に行うことができます。
ここでは画像のように2本指で回転と拡大縮小を同時に行うことができるようになります。

画像の回転はrotationEffect, 拡大縮小はscaleEffectで変更することができます。

RotationGestureでは角度が取得できるので変数angleに保存してrotationEffectに渡します。
MagnificationGestureでは拡大・縮小率が取得できるので変数magnifyに保存してscaleEffectに渡します。

今回は2回目の回転・拡大を1回目の回転・拡大の情報から行うためlastAngle, lastMagnifyを利用しています。
ジェスチャーのたびに画像が初期状態に戻っていい場合にはコメントアウトしてください。

//
//  ContentView.swift
//

import SwiftUI

struct ContentView: View {
    @State private var magnify: CGFloat = 1
    @State private var lastMagnify: CGFloat = 1
    @State private var angle: Angle = .degrees(.zero)
    @State private var lastAngle: Angle = .degrees(.zero)
    
    var body: some View {
        VStack () {
            ZStack () {
                Image("ice_1")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .scaleEffect(self.magnify)
                    .rotationEffect(self.angle)
                    .gesture(RotationGesture()
                        .onChanged{ angle in
                            self.angle = angle + self.lastAngle
                        }
                        .onEnded { angle in
                            self.lastAngle = self.angle
                        }
                    )
                    .simultaneousGesture(MagnificationGesture()
                        .onChanged{ v in
                            let delta = v / self.lastMagnify
                            self.lastMagnify = v
                            self.magnify *= delta
                        }
                        .onEnded{ v in
                            self.lastMagnify = 1
                        }
                    )
                    .clipShape(Circle())
                    .overlay(
                        Circle().stroke(LinearGradient(gradient: Gradient(colors: [.yellow, .red, .purple]), startPoint: .bottomLeading, endPoint: .topTrailing), lineWidth: 5))
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

参考

Gestures | Apple Developer Documentation


    アプリをリリースしました!

    ToDoアプリ

    iCloudを利用したデバイス間データ共有、ダークモードに対応しています。

    リリースしたToDoアプリのスクリーンショット

    IPアドレス履歴保存アプリ

    取得したIPアドレスを確認、位置情報とともに保存できます。

    リリースしたIPアドレス保存アプリのスクリーンショット