Created
October 28, 2023 03:26
-
-
Save overlair/2cfb7f29a5917799920d22c28c40b7f5 to your computer and use it in GitHub Desktop.
UIKit Gestures in SwiftUI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
struct ExampleUIKitGestureViewA: View { | |
var body: some View { | |
Color.blue | |
.overlay { ExampleUIKitGestureViewRepresentableA() } | |
/* | |
can also place it behind if hits are disabled on attaching view, | |
or you have other views you want to receive gestures that it would block | |
.background { ExampleUIKitGestureViewRepresentable() } | |
*/ | |
} | |
} | |
struct ExampleUIKitGestureViewRepresentableA: UIViewRepresentable { | |
func makeUIView(context: Context) -> some UIView { | |
let v = UIView() | |
/* | |
declare necessary gestures here, and attach them to callbacks in a "Coordinator", or delegate object that implements recognizer functions, or other delegate functions for interactions (like UIDragInteraction) | |
*/ | |
let tap = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.tap)) | |
v.addGestureRecognizer(tap) | |
return v | |
} | |
func updateUIView(_ uiView: UIViewType, context: Context) {} | |
func makeCoordinator() -> Coordinator { | |
Coordinator() | |
} | |
class Coordinator: NSObject, UIGestureRecognizerDelegate { | |
@objc func tap(gesture: UITapGestureRecognizer) { | |
// do something with tap here | |
} | |
} | |
} | |
/* | |
If you'd rather handle the gesture callbacks in a SwiftUI view, you can use a callback function and simply pass along the gesture parameters | |
*/ | |
struct ExampleUIKitGestureViewB: View { | |
var body: some View { | |
Color.blue | |
.overlay { ExampleUIKitGestureViewRepresentableB(event: handle) } | |
} | |
func handle(_ event: ExampleUIKitGestureEvent) { | |
// handle gesture callback in SwiftUI view | |
} | |
} | |
enum ExampleUIKitGestureEvent { | |
case tap(UITapGestureRecognizer) | |
} | |
struct ExampleUIKitGestureViewRepresentableB: UIViewRepresentable { | |
let event: (ExampleUIKitGestureEvent) -> () | |
func makeUIView(context: Context) -> some UIView { | |
let v = UIView() | |
let tap = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.tap)) | |
v.addGestureRecognizer(tap) | |
return v | |
} | |
func updateUIView(_ uiView: UIViewType, context: Context) {} | |
func makeCoordinator() -> Coordinator { | |
Coordinator(event: event) | |
} | |
class Coordinator: NSObject, UIGestureRecognizerDelegate { | |
let event: (ExampleUIKitGestureEvent) -> () | |
init(event: @escaping (ExampleUIKitGestureEvent) -> Void) { | |
self.event = event | |
} | |
@objc func tap(gesture: UITapGestureRecognizer) { | |
event(.tap(gesture)) | |
} | |
} | |
} | |
/* | |
For handling raw touches, you'll need to define your own custom UIView | |
*/ | |
class TouchHandlingUIView: UIView { | |
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
// do something with touches | |
} | |
} | |
/* | |
can use this in place of a standard UIView | |
func makeUIView(context: Context) -> some UIView { | |
let v = TouchHandlingUIView() | |
return v | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment