Isn't there an easy way to pinch to zoom in an image in Swiftui?

前端 未结 7 1504
自闭症患者
自闭症患者 2020-12-28 08:07

I want to be able to resize and move an image in SwiftUI (like if it were a map) with pinch to zoom and drag it around.

With UIKit I embedded the image into a

7条回答
  •  不思量自难忘°
    2020-12-28 08:41

    struct DetailView: View {
        var item: MenuItem
        @State private var zoomed:Bool = false
        @State var scale: CGFloat = 1.0
        @State var isTapped: Bool = false
        @State var pointTaped: CGPoint = CGPoint.zero
        @State var draggedSize: CGSize = CGSize.zero
        @State var previousDraged: CGSize = CGSize.zero
    
        var width = UIScreen.main.bounds.size.width
        var height = UIScreen.main.bounds.size.height
    
        var body: some View {
            GeometryReader {  reader in
                VStack(alignment: .center) {
                    ScrollView(){
                        HStack {
                            ScrollView(.vertical){
                                Image(self.item.mainImage)
                                    .resizable()
                                    .scaledToFill()
                                    .animation(.default).offset(x: self.draggedSize.width, y: 0)
                                    .scaleEffect(self.scale).scaleEffect(self.isTapped ? 2 : 1, anchor: UnitPoint(x : (self.pointTaped.x) / (reader.frame(in : .global).maxX),y: (self.pointTaped.y) / (reader.frame(in : .global).maxY )))
                                    .gesture(TapGesture(count: 2)
                                        .onEnded({ value in
                                            self.isTapped = !self.isTapped
                                        })
                                        .simultaneously(with: DragGesture(minimumDistance: 0, coordinateSpace: .global)  .onChanged { (value) in
                                            self.pointTaped = value.startLocation
                                            self.draggedSize = CGSize(width: value.translation.width + self.previousDraged.width, height: value.translation.height + self.previousDraged.height)
                                        }
                                        .onEnded({ (value) in
                                            let offSetWidth = (reader.frame(in :.global).maxX * self.scale) - (reader.frame(in :.global).maxX) / 2
                                            let newDraggedWidth = self.previousDraged.width * self.scale
                                            if (newDraggedWidth > offSetWidth){
                                                self.draggedSize = CGSize(width: offSetWidth / self.scale, height: value.translation.height + self.previousDraged.height)
                                            }
                                            else if (newDraggedWidth < -offSetWidth){
                                                self.draggedSize = CGSize(width:  -offSetWidth / self.scale, height: value.translation.height + self.previousDraged.height)
                                            }
                                            else{
                                                self.draggedSize = CGSize(width: value.translation.width + self.previousDraged.width, height: value.translation.height + self.previousDraged.height)
                                            }
                                            self.previousDraged =  self.draggedSize
                                        })))
    
                                    .gesture(MagnificationGesture()
                                        .onChanged { (value) in
                                            self.scale = value.magnitude
    
                                    }.onEnded { (val) in
                                        //self.scale = 1.0
                                        self.scale = val.magnitude
                                        }
                                )
                            }
                        }
    
                            HStack {
                                Text(self.item.description)
                                    .foregroundColor(Color.black)
                                    .multilineTextAlignment(.leading)
                                    .padding(4)
                            }
                    }
                }.navigationBarTitle("Menu Detail")
            }
        }
    }
    

提交回复
热议问题