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
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")
}
}
}