I have a SwiftUI view that uses Geometry so that I can manipulate an Image by touch gestures. It stopped working under a .sheet view in iOS 16.4. It works fine in a normal view, just not in sheet view.
I believe this is a Bug on Apple's end and I am open for any alternative ideas as it's not doing good to my app customers. I don't like to but I could just go back to a UIViewRepresentative.
Here's some Code for Testing
import SwiftUI
struct SheetImageTest: View {
@State var showView = false
var body: some View {
Button(action: {showView.toggle()}){
Text("Show Image")
}
.sheet(isPresented: $showView) {
ImageTouchableView(image: "YourImage")
}
}
}
struct SheetImageTest_Previews: PreviewProvider {
static var previews: some View {
SheetImageTest()
}
}
Manipulative Image View
import SwiftUI
struct ImageTouchableView: View {
let image: String
//Scale Stuff
@State private var scale: CGFloat = 1.0
@State private var tapped = false
//Drag Stuff
@State private var location: CGPoint = CGPoint(x: 50, y: 50)
@GestureState private var fingerLocation: CGPoint? = nil
@GestureState private var startLocation: CGPoint? = nil // 1
var simpleDrag: some Gesture {
DragGesture()
.onChanged { value in
var newLocation = startLocation ?? location // 3
newLocation.x += value.translation.width
newLocation.y += value.translation.height
self.location = newLocation
}.updating($startLocation) { (value, startLocation, transaction) in
startLocation = startLocation ?? location // 2
}
}
//Size Stuff
@State private var size = CGSize(width: 100, height: 100)
var pinchZoom: some Gesture {
MagnificationGesture()
.onChanged { value in
self.scale = value.magnitude
}
}
var body: some View {
GeometryReader { geometry in
Image(image)
.resizable()
.scaleEffect(scale)
.scaledToFit()
.position(location)
.gesture(simpleDrag)
.gesture(pinchZoom)
.onAppear(){
location = CGPoint(x: geometry.size.width/2, y: geometry.size.height/2)
size = CGSize(width: geometry.size.width, height: geometry.size.height)
}
.frame(width: size.width, height: size.height)
.onTapGesture(count: 2, perform: {
tapped.toggle()
if tapped {
scale += 1.0
location = CGPoint(x: geometry.size.width/2, y: geometry.size.height/2)
} else {
scale -= 1.0
location = CGPoint(x: geometry.size.width/2, y: geometry.size.height/2)
size = CGSize(width: geometry.size.width, height: geometry.size.height)
}
})
.animation(.default, value: scale)
}
}
}
struct ImageTouchableView_Previews: PreviewProvider {
static var previews: some View {
ImageTouchableView(image: "YourImage")
}
}