Skip to content

Instantly share code, notes, and snippets.

@ingconti
Created July 4, 2022 14:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ingconti/124d549e2671fd91d86144bc222d171a to your computer and use it in GitHub Desktop.
Save ingconti/124d549e2671fd91d86144bc222d171a to your computer and use it in GitHub Desktop.
// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
Image(systemName: "paperplane")
.renderingMode(.template)
.resizable()
.foregroundColor(.red)
.scaledToFit()
.draggableAndZoomable()
}
}
//
// DragAndZoomViewModifier.swift
//
import SwiftUI
// Handle dragging
struct DraggableAndZoomableView: ViewModifier {
@GestureState private var scaleState: CGFloat = 1
@GestureState private var offsetState = CGSize.zero
@State private var offset = CGSize.zero
@State private var scale: CGFloat = 1
func resetStatus(){
self.offset = CGSize.zero
self.scale = 1
}
init(){
resetStatus()
}
var zoomGesture: some Gesture {
MagnificationGesture()
.updating($scaleState) { currentState, gestureState, _ in
gestureState = currentState
}
.onEnded { value in
scale *= value
}
}
var dragGesture: some Gesture {
DragGesture()
.updating($offsetState) { currentState, gestureState, _ in
gestureState = currentState.translation
}.onEnded { value in
offset.height += value.translation.height
offset.width += value.translation.width
}
}
var doubleTapGesture : some Gesture {
TapGesture(count: 2).onEnded { value in
resetStatus()
}
}
func body(content: Content) -> some View {
content
.scaleEffect(self.scale * scaleState)
.offset(x: offset.width + offsetState.width, y: offset.height + offsetState.height)
.gesture(SimultaneousGesture(zoomGesture, dragGesture))
.gesture(doubleTapGesture)
}
}
// Wrap `draggable()` in a View extension to have a clean call site
extension View {
func draggableAndZoomable() -> some View {
return modifier(DraggableAndZoomableView())
}
}
@rbrownme
Copy link

An image can be dragged off the screen and then there’s no way to double tap it to reset it’s location.
I tried creating a button to do this but haven’t been able to figure out how to call resetStatus() or init().
Is this possible?
I new at this and still learning. Any feedback will be appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment