bravo's blog

多分ググっても出てこないようなプログラミング記事を目指します!

SwiftUI MagnificationGestureでViewを拡大縮小するサンプルを色々調べた結果行き着いたサンプルコードを書く

SwiftUIのMagnificationGestureで拡大縮小を行い、且つ、拡大縮小の状態を保持して、且つジェスチャーも自然にできるサンプルを探してたけど、全てを満たすコードが無かったのでここに書いておきます。画像はImage構造体を使いますが、URLから取って来る都合で、UIImageも少し拡張しています。

import SwiftUI

extension UIImage {
   public convenience init(url: String) {
       let url = URL(string: url)
       do {
           let data = try Data(contentsOf: url!)
           self.init(data: data)!
           return
       } catch let err {
           print("Error : \(err.localizedDescription)")
       }
       self.init()
   }
}

struct MagView: View {
    @State private var currentAmount: CGFloat = 1
    @State private var finalAmount: CGFloat = 1
    let image = UIImage(url: "https://picsum.photos/800")
    
    func reset() {
        self.finalAmount = 1
        self.currentAmount = 1
    }
    
    init() {
        reset()
    }
    
    var body: some View {
        VStack {
            Image(uiImage: image)
                .resizable()
                .scaleEffect(finalAmount * currentAmount)
                .frame(width: image.size.width, height: image.size.height)
                .gesture(
                    MagnificationGesture()
                        .onChanged { amount in
                            self.currentAmount = amount
                        }
                        .onEnded { amount in
                            self.finalAmount *= self.currentAmount
                            self.currentAmount = 1
                        }
                )
            Text("Current:\(CGFloattoString(currentAmount))").font(.system(size:24))
            Text("Final:\(CGFloattoString(finalAmount))").font(.system(size:24))
            Text("Scale:\(CGFloattoString(finalAmount * currentAmount))").font(.system(size:24))
            Button("Reset", action: reset)
        }
    }
}

重要な変数はcurrentAmountfinalAmountで、finalAmountは基礎になる倍率値、currentAmountはジェスチャーが有効になっている間の変化率です。ジェスチャーが終了したらfinalAmountに反映し、再度ジェスチャーが行われても拡大縮小のスムーズさを一定に保ちます。

参考記事

www.hackingwithswift.com

PR