How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem?

前端 未结 14 857
遥遥无期
遥遥无期 2020-11-28 22:48

I got the opposite issue from here. By default in iOS7, back swipe gesture of UINavigationController\'s stack could pop the presented ViewCon

相关标签:
14条回答
  • 2020-11-28 23:07

    This is the best way to enable/ disable swipe to pop view controller in iOS 10, Swift 3 :

    For First Screen [ Where you want to Disable Swipe gesture ] :

    class SignUpViewController : UIViewController,UIGestureRecognizerDelegate {
    
    //MARK: - View initializers
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        swipeToPop()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    func swipeToPop() {
    
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
        self.navigationController?.interactivePopGestureRecognizer?.delegate = self;
    }
    
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    
        if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
            return false
        }
        return true
    } }
    

    For middle screen [ Where you want to Enable Swipe gesture ] :

    class FriendListViewController : UIViewController {
    
    //MARK: - View initializers
    override func viewDidLoad() {
    
        super.viewDidLoad()
        swipeToPop()
    }
    
    func swipeToPop() {
    
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
        self.navigationController?.interactivePopGestureRecognizer?.delegate = nil;
    } }
    
    0 讨论(0)
  • 2020-11-28 23:07

    If you want this behaviour everywhere in your app and don't want to add anything to individual viewDidAppear etc. then you should create a subclass

    class QFNavigationController:UINavigationController, UIGestureRecognizerDelegate, UINavigationControllerDelegate{
        override func viewDidLoad() {
            super.viewDidLoad()
            interactivePopGestureRecognizer?.delegate = self
            delegate = self
        }
    
        override func pushViewController(_ viewController: UIViewController, animated: Bool) {
            super.pushViewController(viewController, animated: animated)
            interactivePopGestureRecognizer?.isEnabled = false
        }
    
        func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
            interactivePopGestureRecognizer?.isEnabled = true
        }
    
        // IMPORTANT: without this if you attempt swipe on
        // first view controller you may be unable to push the next one
        func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            return viewControllers.count > 1
        }
    
    }
    

    Now, whenever you use QFNavigationController you get the desired experience.

    0 讨论(0)
  • 2020-11-28 23:07

    We're all working around some old bugs that haven't been fixed likely because it's "by design." I ran into the freezing problem @iwasrobbed described elsewhere when trying to nil the interactivePopGestureRecognizer's delegate which seemed like it should've worked. If you want swipe behavior reconsider using backBarButtonItem which you can customize.

    I also ran into interactivePopGestureRecognizer not working when the UINavigationBar is hidden. If hiding the navigation bar is a concern for you, reconsider your design before implementing a workaround for a bug.

    0 讨论(0)
  • 2020-11-28 23:08

    For those who are still having trouble with this, try separating the two lines as below.

    override func viewDidLoad() {
        self.navigationController!.interactivePopGestureRecognizer!.delegate = self
        ...
    
    override func viewWillAppear(_ animated: Bool) {
        self.navigationController!.interactivePopGestureRecognizer!.isEnabled = true
        ...
    

    Obviously, in my app,

    interactivePopGestureRecognizer!.isEnabled

    got reset to false before the view was shown for some reason.

    0 讨论(0)
  • 2020-11-28 23:09

    Setting a custom back button disable the swipe back feature.

    The best thing to do to keep it is to subclass UINavigationViewController and set itself as the interactivePopGestureRecognizer delegate; then you can return YES from gestureRecognizerShouldBegin to allow the swipe back.

    For example, this is done in AHKNavigationController

    And a Swift version here: https://stackoverflow.com/a/43433530/308315

    0 讨论(0)
  • 2020-11-28 23:15

    Swift 3:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        self.navigationController?.interactivePopGestureRecognizer?.delegate = self
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return (otherGestureRecognizer is UIScreenEdgePanGestureRecognizer)
    }
    
    0 讨论(0)
提交回复
热议问题