SwiftUI:捏以放大图像

时间:2019-12-21 14:43:30

标签: ios swift swiftui

我想允许用户在SwiftUI中放大图像。我认为最好的方法是使用MagnificationGesture,然后再加上答案here,最终得到以下代码:

// outside of `var body: some View`
@State private var scale: Int = 1.0
@State private var lastScale: Int = 1.0

// Image 
Image("dog")
.resizable()
.aspectRatio(contentMode: .fit)
.gesture(MagnificationGesture()
    .onChanged { val in
        let delta = val / self.lastScale
        self.lastScale = val
        let newScale = self.scale * delta
        self.scale = newScale
    }
    .onEnded { _ in
        self.lastScale = 1.0
    }
)
.scaleEffect(scale)

此代码可以很好地处理放大倍率,但不允许用户放大特定区域。相反,它总是在图像的中间放大。

我该如何在SwiftUI中处理图像上的缩小缩放行为?

提前谢谢!

1 个答案:

答案 0 :(得分:4)

该代码通过在放大手势之外添加拖动手势来创建捏合缩放效果。使用viewState可以在使用拖动手势时更改偏移位置。

struct ContentView: View {

    @State private var scale: CGFloat = 1.0
    @State private var lastScale: CGFloat = 1.0
    @State private var viewState = CGSize.zero

    var body: some View {

    Image("dog")
        .resizable()
        .aspectRatio(contentMode: .fit)
        .animation(.spring())
        .offset(x: viewState.width, y: viewState.height)
        .gesture(DragGesture()
            .onChanged { val in
                self.viewState = val.translation
            }
        )
        .gesture(MagnificationGesture()
            .onChanged { val in
                let delta = val / self.lastScale
                self.lastScale = val
                if delta > 0.94 { // if statement to minimize jitter
                    let newScale = self.scale * delta
                    self.scale = newScale
                }
            }
            .onEnded { _ in
                self.lastScale = 1.0
            }
        )
        .scaleEffect(scale)
        }
}

添加了“ if”语句,以最大程度地减少由于频繁更新而引起的抖动。 0.94的值没有什么特别的,只需通过反复试验即可设置。

添加了.animation(spring())语句,以提供更自然的拖动效果。