1

I am trying to scale a view horizontally using scaleEffect and MagnificationGesture. It is almost working as I want with the exception that the ScrollView does not resize when its child view resizes.

Is there a fix for this? Any solution would be greatly appreciated.

To reproduce:

  1. run the code below
  2. scale up the image horizontally with the pinch gesture
  3. notice that the ScrollView scrolls as if the image still has the same size.
struct ContentView: View {

    @State private var currentAmount: CGFloat = 0
    @State private var finalAmount: CGFloat = 1

    var body: some View {
        ScrollView(.horizontal) {
            Image(systemName: "star")
                .resizable()
                .scaledToFit()
                .scaleEffect(x: finalAmount + currentAmount, y: 1)
                .gesture(
                    MagnificationGesture()
                        .onChanged { amount in
                            self.currentAmount = amount - 1
                        }
                        .onEnded { amount in
                            self.finalAmount += self.currentAmount
                            self.currentAmount = 0
                        }
                )
        }
        .frame(maxHeight: 300)
    }
}
Isaak
  • 1,107
  • 2
  • 11
  • 29

1 Answers1

1

This view does it.

struct HorizontalScaleView<Content: View>: View {

    @ViewBuilder var content: Content

    @State private var currentAmount: CGFloat = 0
    @State private var finalAmount: CGFloat = 1

    var body: some View {
        GeometryReader { geo in
            ScrollView(.horizontal) {
                content
                    .scaledToFit()
                    .scaleEffect(x: finalAmount + currentAmount, y: 1)
                    .frame(width: (finalAmount + currentAmount) * geo.size.width, height: geo.size.width)
                    .gesture(
                        MagnificationGesture()
                            .onChanged { amount in
                                self.currentAmount = amount - 1
                            }
                            .onEnded { _ in
                                if self.finalAmount + self.currentAmount >= 1 {
                                    self.finalAmount += self.currentAmount
                                } else {
                                    self.finalAmount = 1
                                }
                                self.currentAmount = 0
                            }
                    )
            }
        }
    }
}
Isaak
  • 1,107
  • 2
  • 11
  • 29