It uses navigation that allows you to go back even if you swipe the middle of the screen as shown in the code here. In this case, if a SwiftUI view exists in the viewControllers of the navigation, the SwiftUI view will not accept the action if you cancel the return operation in the middle. Is there a solution to this?
https://gist.github.com/policante/33a2d11b0501052d230c1f213dcacde3
class BaseNavigationController: UINavigationController, UINavigationControllerDelegate {
var interactivePopTransition: UIPercentDrivenInteractiveTransition!
override func viewDidLoad() {
self.delegate = self
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
addPanGesture(viewController)
}
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if operation == .pop {
return NavigationPopTransition()
}else{
return nil
}
}
func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
if animationController.isKind(of: NavigationPopTransition.self) {
return interactivePopTransition
}else{
return nil
}
}
private func addPanGesture(_ viewController: UIViewController){
let popRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePanRecognizer(recognizer:)))
viewController.view.addGestureRecognizer(popRecognizer)
}
@objc func handlePanRecognizer(recognizer: UIPanGestureRecognizer){
var progress = recognizer.translation(in: self.view).x / self.view.bounds.size.width
progress = min(1, max(0, progress))
print(progress)
if recognizer.state == .began {
self.interactivePopTransition = UIPercentDrivenInteractiveTransition()
self.popViewController(animated: true)
}else if recognizer.state == .changed {
interactivePopTransition.update(progress)
}else if recognizer.state == .ended || recognizer.state == .cancelled {
if progress > 0.2 {
interactivePopTransition.finish()
}else{
interactivePopTransition.cancel()
}
interactivePopTransition = nil
}
}
}
struct SampleView: View {
var body: some View {
NavigationLink(
destination: SampleView(),
label: {
Text("LINK")
})
}
}
let view: UIHostingController = UIHostingController(rootView: SampleView())
let nav = BaseNavigationController[enter image description here][1](rootViewController: view)
present(nav, animated: true, completion: nil)