画像を拡大・縮小するにはMagnificationGestureを使うと可能です。Gestureを使うのでピンチイン・ピンチアウトになります。
MagnificationGesture
最初に、MagnificationGesture にサンプルコードがあるのでそのまま実装してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import SwiftUI struct ContentView: View { @GestureState var magnifyBy = CGFloat(1.0) var magnification: some Gesture { MagnificationGesture() .updating($magnifyBy) { currentState, gestureState, transaction in gestureState = currentState } } var body: some View { Circle() .frame(width: 100 * magnifyBy, height: 100 * magnifyBy, alignment: .center) .gesture(magnification) } } |
これを実行してみると、updatingを使っているのでGesture後の状態は保持されず元に戻ります。gestureが終わればリセットするという説明です
確かにピンチイン・ピンチアウトができるのですが、これでは画像を拡大縮小したままにはできないので他の機能を使います。
Callbacks
MagnificationGestureで使うCallbackのスペックで、画像を拡大縮小させつつ表示するにはonChangedが使えます。
updating: Gestureが変化したときにgesture state propertyをアップデートする、ただし値は保持されない
1 2 3 |
func updating<State>(_ state: GestureState<State>, body: @escaping (CGFloat, inout State, inout Transaction) -> Void) -> GestureStateGesture<MagnificationGesture, State> |
onChanged:Gestureが変化したときに実行するアクションを追加
1 2 |
func onChanged(_ action: @escaping (CGFloat) -> Void) -> _ChangedGesture<MagnificationGesture> |
onEnded:Gestureが終わった時のアクションを追加
1 2 |
func onEnded(_ action: @escaping (CGFloat) -> Void) -> _EndedGesture<MagnificationGesture> |
MagnificationGesture.Value:Gestureの変化の値, CGFloat
1 |
typealias MagnificationGesture.Value = CGFloat |
画像の拡大
Gestureを使う前に、
画像を拡大するにはImageのサイズ変更を反映させる必要があるため、中間的に
resizableとscaleEffectを使います。
- resizable: リサイズ可能なスペースにフィットするようにモードを設定
- scaleEffect: 指定された垂直および水平のサイズでスケーリング
適当な画像を(sample_img@2x.jpg) Assets.xcassets に配置
ここではボタンでスケーリングさせることを確認します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import SwiftUI struct ContentView: View { @State var scaleValue: CGFloat = 1.0 var body: some View { VStack { Image("sample_img") .resizable() .scaleEffect(scaleValue) .frame(width: 200, height: 200) Button(action: { self.scaleValue += 0.2 }){ Text("Button") } .padding(.top, 200) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } |
ボタンをタップすることでサイズが増加していきました
サンプルコード
ボタンを使ってサイズを変化させたところをGestureを使います。
ContentView
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import SwiftUI struct ContentView: View { @State var scaleValue: CGFloat = 1.0 var body: some View { Image("sample_img") .resizable() .scaleEffect(scaleValue) .frame(width: 200, height: 200) .gesture(MagnificationGesture() .onChanged { value in self.scaleValue = value } ) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } |
PreviewやSimulatorで確認するときは(option) キーを押しながらマウスを操作するとピンチイン、ピンチアウトが確認できます。あるいは実機
References:
Gestures | Apple Developer Documentation
MagnificationGesture – SwiftUI | Apple Developer
MagnificationGesture – SwiftUI | Apple Developer
onChanged(_:) – MagnificationGesture | Apple Developer
onEnded(_:) – MagnificationGesture | Apple Developer
Image – SwiftUI | Apple Developer Documentation
scaleEffect(_:anchor:) – SecureField | Apple Developer
resizable(capInsets:resizingMode:) – Apple Developer