9

I'm trying to zoom and pan on an Image in SwiftUI for a Catalyst app. There is no PanGesture, but ScrollView seems to work well on both iPad and Mac.  I just can't scroll around on the magnified image.  

struct TestScrollView: View {
    @State var scale: CGFloat = 1.0
    
    var body: some View {
        VStack {
            ScrollView([.horizontal,.vertical], showsIndicators: false) {
                    Image("image")
                        .resizable()
            }
            .gesture(MagnificationGesture()
            .onChanged({ (scale) in
                self.scale = scale
            }))
                .scaleEffect(self.scale)
        }
    }
}

And with the following code...

ScrollView([.horizontal,.vertical], showsIndicators: false) {
    Image("large_image")
        .resizable()
        .gesture(MagnificationGesture()
                    .onChanged({ (scale) in
                        self.scale = scale
                    }))
        .scaleEffect(self.scale)
}

...I get this:

test video

It seems to scroll right a lot and it gets cut off on the left side.

Luke Morse
  • 395
  • 2
  • 12

1 Answers1

7

It seems that the content's frame size stays the same after applying scaleEffect, and that's why you are unable to scroll inside ScrollView. There's nowhere to scroll to. You can fix the problem by manually specifying the frame size after scaling. If you don't know the original frame size, use GeometryReader to calculate the frame size after scaling dynamically.

ScrollView([.horizontal, .vertical], showsIndicators: false) {
    Image(systemName: "square.fill")
        .resizable()
        .frame(width: 200, height: 200)
        .scaleEffect(self.scale)
        .frame(
            width: 200 * self.scale,
            height: 200 * self.scale
        )
}
.gesture(magnificationGesture)

Also, your MagnificationGesture's onChanged implementation has some problems. Refer to this answer by James.

Kousuke Ariga
  • 691
  • 9
  • 10