Search code examples
iosswiftswiftui

How to Disable interativePopGestureRecognizer when Navigating from UIKit to SwiftUI View


I am navigating my swiftUI view from UIKit, And I am trying to disable back swipe, I did some R&D no code is working for me. I wanted to disable only in one controller not all the controller.

Project Minimum target version : iOS 15.0

navigationController?.interactivePopGestureRecognizer?.isEnabled = false

This is my code flow:

extension UIViewController {
    func navigateHostingView<T: View>(
        _ hosting: UIHostingController<T>,
        hidesBottomBarWhenPushed: Bool = true,
        setNavigationBarHidden: Bool = true,
        pushAnimation: Bool = true
    ) {
        hosting.hidesBottomBarWhenPushed = hidesBottomBarWhenPushed
        navigationController?.setNavigationBarHidden(setNavigationBarHidden, animated: false)
        navigationController?.interactivePopGestureRecognizer?.isEnabled = false
        navigationController?.pushViewController(hosting, animated: pushAnimation)
    }
}
func navigateToMySwiftUIView(myData: MyData, questions: [QuestionModel]) {
    let hosting = UIHostingController(
        rootView: MySwiftUIView(
            myData: myData,
            questions: questions, onDismiss: { [weak self] isThankyou in
                self?.showThankyouScreen(isThankyou)
            })
        .environment(\.navigationController, navigationController)
    )
    navigateHostingView(hosting)
}

Any suggestion that would work for me. Thankyou


Solution

  • You can subclass UIHostingController and change interactivePopGestureRecognizer?.isEnabled's in viewWillAppear and viewWilLDisappear method.

    class DisableSwipeBack<T: View>: UIHostingController<T> {
        private var isEnableSwipeBack: Bool = true
        
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            
            isEnableSwipeBack = navigationController?.interactivePopGestureRecognizer?.isEnabled ?? false
            navigationController?.interactivePopGestureRecognizer?.isEnabled = false
        }
        
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            navigationController?.interactivePopGestureRecognizer?.isEnabled = isEnableSwipeBack
        }
    }