Skip to content

Instantly share code, notes, and snippets.

@treboc
Created January 15, 2024 12:42
Show Gist options
  • Save treboc/0881f1de77aee3029247ee56ffc96f1d to your computer and use it in GitHub Desktop.
Save treboc/0881f1de77aee3029247ee56ffc96f1d to your computer and use it in GitHub Desktop.
//
// CustomNavigationStack.swift
//
import SwiftUI
struct CustomNavigationStack<Content: View>: View {
@Binding var path: NavigationPath
@ViewBuilder var content: Content
@State private var interactivePopGestureRecognizer: UIScreenEdgePanGestureRecognizer = {
let gesture = UIScreenEdgePanGestureRecognizer()
gesture.name = UUID().uuidString
gesture.edges = UIRectEdge.left
gesture.isEnabled = true
return gesture
}()
var body: some View {
NavigationStack(path: $path) {
content
.background {
AttachPopGestureView(gesture: $interactivePopGestureRecognizer)
}
}
}
}
private struct AttachPopGestureView: UIViewRepresentable {
@Binding var gesture: UIScreenEdgePanGestureRecognizer
func makeUIView(context: Context) -> some UIView {
UIView()
}
func updateUIView(_ uiView: UIViewType, context: Context) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) {
if let parentVC = uiView.parentViewController {
if let navigationController = parentVC.navigationController {
// To prevent duplication
guard !(navigationController.view.gestureRecognizers?
.contains(where: { $0.name == gesture.name }) ?? true) else { return }
navigationController.addInteractivePopGesture(gesture)
}
}
}
}
}
// MARK: - Helper
private extension UINavigationController {
func addInteractivePopGesture(_ gesture: UIPanGestureRecognizer) {
guard let gestureSelector = interactivePopGestureRecognizer?.value(forKey: "targets") else { return }
gesture.setValue(gestureSelector, forKey: "targets")
view.addGestureRecognizer(gesture)
}
}
private extension UIView {
var parentViewController: UIViewController? {
sequence(first: self) { $0.next }.first(where: { $0 is UIViewController }) as? UIViewController
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment