无法在缩放的 ScrollView 中平移图像?

Posted

技术标签:

【中文标题】无法在缩放的 ScrollView 中平移图像?【英文标题】:Cannot pan image in zoomed ScrollView? 【发布时间】:2021-10-21 23:41:52 【问题描述】:

我想构建一个简单的视图,让我可以在滚动视图中显示图像,并让用户通过捏合来缩放图像并进行平移。

我环顾四周并从thisScrollView开始:

struct TestView: View 
    
    var body: some View 
        
        ScrollView 
            Image("test")
                .border(Color(.yellow))
        
        .border(Color(.red))
        
    

这将无法处理缩放。

然后我这样做了:

struct TestView: View 


    /// https://wp.usatodaysports.com/wp-content/uploads/sites/88/2014/03/sunset-in-the-dolos-mikadun.jpg
    var image = UIImage(named: "test")!
    @State var scale: CGFloat = 1.0
    @State var lastScaleValue: CGFloat = 1.0

    var body: some View 


        GeometryReader  geo in

            ScrollView([.vertical, .horizontal], showsIndicators: false)

                ZStack

                    Image(uiImage: image)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: geo.size.width, height: geo.size.width)
                        .scaleEffect(scale)
                        .gesture(MagnificationGesture().onChanged  val in
                            let delta = val / self.lastScaleValue
                            self.lastScaleValue = val
                            var newScale = self.scale * delta
                            if newScale < 1.0 
                                newScale =  1.0
                            
                            scale = newScale
                        .onEndedval in
                            lastScaleValue = 1
                        )

                

            
            .frame(width: geo.size.width, height: geo.size.width)
            .border(Color(.red))
            .background(Color(.systemBackground).edgesIgnoringSafeArea(.all))

        

    


这允许我放大和缩小,但是我无法平移图像:

如何编写代码以便支持缩放和平移?

【问题讨论】:

我可能会错过它,但在您的代码中,您只是缩放而不是旋转。您必须为旋转添加一个变量。就像你做规模一样。 【参考方案1】:

为了获得平移功能,您必须更改图像容器的大小,在本例中为 ZStack。 所以首先我们需要一个变量来保存当前最新的刻度值。

@State var scaledFrame: CGFloat = 1.0

然后在每次手势结束时更改容器的大小。

 ZStack
                        Image(uiImage: image)
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: geo.size.width, height: geo.size.width )
                            .scaleEffect(scale)
                            .gesture(MagnificationGesture().onChanged  val in
                                let delta = val / self.lastScaleValue
                                self.lastScaleValue = val
                                var newScale = self.scale * delta
                                if newScale < 1.0 
                                    newScale =  1.0
                                
                                scale = newScale
                            .onEndedval in
                                scaledFrame = scale//Update the value once the gesture is over
                                lastScaleValue = 1
                                
                            )
                            .draggable()
                    
                    .frame(width: geo.size.width * scaledFrame, height: geo.size.width * scaledFrame)
                    //change the size of the frame once the drag is complete

这是由于 ScrollView 的工作方式,当您放大时,容器的实际大小没有改变,因此 ScrollView 只是相应地移动。

【讨论】:

以上是关于无法在缩放的 ScrollView 中平移图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 as3 中平滑图像的“缩放”和“平移”

iOS 7 缩放不能在具有 AutoLayout 的 ScrollView 中工作,但在 iOS8/9 中工作

无法在 UIScrollView 中缩放图像

按下缩放按钮时如何缩放 ScrollView 图像?

SwiftUI - 缩放、缩放和裁剪图像

带有图像的 UIScrollView - 如何不缩放其中一个