【问题标题】:Cannot pan image in zoomed ScrollView?无法在缩放的 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
                        }.onEnded{val in
                            lastScaleValue = 1
                        })

                }

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

        }

    }

}

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

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

【问题讨论】:

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

标签: swiftui scrollview


【解决方案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
                            }.onEnded{val 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 只是相应地移动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2016-07-22
    • 2011-09-10
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多