MagnificationGestureで拡大縮小の最大値・最小値を設定する


*****
(2021.9.9 追記)
こちらのコードが素晴らしかったです😭
https://pastebin.com/embed_js/rpSRTddm
(https://stackoverflow.com/questions/58341820/isnt-there-an-easy-way-to-pinch-to-zoom-in-an-image-in-swiftui　からリンク）

 imageView.contentMode = .scaleAspectFill
を
    imageView.contentMode = .scaleAspectFit
に書き換えたらよこ
*****

方々参考にさせていただきながら、

・ピンチイン・ピンチアウトができる
・拡大縮小の最大値・最小値を設定できる
・ドラッグで移動できる

シンプルめなものをまとめたのでシェアします。

```swift
struct TestPhoto: View {
    @State var lastValue: CGFloat = 1.0
    @State var scale: CGFloat = 1.0
    @State private var textOffset: CGSize = CGSize.zero
    @State var dragStartPosition: CGPoint = CGPoint.zero
    @State var absolutelyScale: CGFloat = 1.0
    @State var isDragging:Bool = false
    
    var drag: some Gesture {
        DragGesture()
            .onChanged { gesture in
                if self.isDragging == false {
                    self.dragStartPosition = CGPoint(x: self.textOffset.width, y: self.textOffset.height)
                    self.isDragging = true
                }
                self.textOffset =  CGSize(width: gesture.translation.width + self.dragStartPosition.x,
                                          height: gesture.translation.height + self.dragStartPosition.y)
            }
            .onEnded { gesture in
                self.isDragging = false
            }
    }
    var body: some View {
        Image("photo")
            .resizable()
            .scaledToFill()      // 縦横比を維持しながらフレームを埋める
            .frame(width: 300, height: 300)
            .scaleEffect(self.scale)
            .offset(textOffset)
            .gesture(drag)
            .gesture(MagnificationGesture()
                        .onChanged { value in
                            let maxScale: CGFloat = 5.0 // 最大値を定義
                            let minScale: CGFloat = 1.0 // 最小値を定義
                            // 初期サイズに対する比率
                            // 前回の値から拡大率を計算する
                            var delta = value / self.lastValue
                            
                            if (absolutelyScale * delta < minScale){
                                delta = minScale
                            }else if (absolutelyScale * delta > maxScale){
                                delta = maxScale
                            }else{
                                // 現在の拡大率を再設定する
                                self.scale = self.scale * delta
                                // 現在の拡大率を覚えておく
                                self.lastValue = value
                                self.absolutelyScale = self.absolutelyScale * delta
                            }
                        }
                        .onEnded { value in
                            // 次のジェスチャーイベントではvalueはまた1.0から始まるため
                            // ジェスチャーイベント完了時に1.0に戻しておく
                            self.lastValue = 1.0
                        }
            )
     }
}


```

参考
https://software.small-desk.com/development/2020/05/18/tips-swiftui-viewdrag/

https://stackoverflow.com/questions/58341820/isnt-there-an-easy-way-to-pinch-to-zoom-in-an-image-in-swiftui

https://software.small-desk.com/development/2021/06/28/swiftui-pinch-and-drag/