Action to Navigation bar back button

前端 未结 6 1499
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-19 20:06

I want to show an alert with Confirmation when user clicks on back button. This is how I\'m trying to add action.

self.navigationItem.hidesBackButton = true
         


        
相关标签:
6条回答
  • 2020-12-19 20:51

    You need add custom back button to Navigation bar, and add action to it

          let backButton = UIBarButtonItem (image: UIImage(named: "ico-nav-prev")!, style: .plain, target: self, action: #selector(GoToBack))
          self.navigationItem.leftBarButtonItem = backButton
          self.navigationItem.hidesBackButton = true
    
         func GoToBack(){
    
            self.navigationController!.popViewController(animated: true)
    
          }
    
    0 讨论(0)
  • 2020-12-19 20:52

    I don't know what you try to achive, but isn't it a possible solution to do, what you want, whenever vieWillDisappear: got called? This is maybe a matching entrypoint without fiddeling around with the back-bar-button suggested in the other answers.

    Better Another option would be to implement the UINavigationControllerDelegate, set your controller as delegate and then implement your alert in navigationController(_:willShow:animated:).

    Take a look here for reference.

    0 讨论(0)
  • 2020-12-19 20:55

    I found a solution!

    I tested it on iOS 11 and iOS 13 and it works fine :)

    protocol CustomNavigationViewControllerDelegate {
        func shouldPop() -> Bool
    }
    
    class CustomNavigationViewController: UINavigationController, UINavigationBarDelegate {
        var backDelegate: CustomNavigationViewControllerDelegate?
    
        func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
            return backDelegate?.shouldPop() ?? true
        }
    }
    
    class SecondViewController: UIViewController, CustomNavigationViewControllerDelegate {
        override func viewDidLoad() {
            super.viewDidLoad()
    
            (self.navigationController as? CustomNavigationViewController)?.backDelegate = self
        }
    
        func shouldPop() -> Bool {
            if (needToShowAlert) {
                showExitAlert()
                return false
    
            } else {
                return true
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-19 20:56

    This might help. This wont override back action, but you can do additional task.

    Objective c

    -(void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        if(self.isMovingFromParentViewController)
        {
            //On click of back or swipe back
        }
        if(self.isBeingDismissed)
        {
            //Dismissed
        }
        NSLog(@"%d",self.isBeingDismissed);
        NSLog(@"%d",self.isMovingFromParentViewController);
    }
    

    Swift

    override func viewWillDisappear(_ animated: Bool)
    {
        super.viewWillDisappear(animated);
        if self.isMovingFromParentViewController
        {
            //On click of back or swipe back
        }
        if self.isBeingDismissed
        {
            //Dismissed
        }
    }
    
    0 讨论(0)
  • 2020-12-19 21:08

    I think this answer should do the job.

    You basically create your button with the default style and register a selector.

    And you might try this for a backButton instead of leftButton:

    Objective-C

    UIBarButtonItem *backBtn = [[UIBarButtonItem alloc] init];
    [desVC.navigationItem setBackBarButtonItem:backBtn];
    

    Swift

    let backBtn = UIBarButtonItem()
    self.navigationItem.backBarButtonItem = backBtn
    
    0 讨论(0)
  • 2020-12-19 21:08

    Call this line of code inside of your ParentViewController's viewDidLoad method not the ChildViewController

    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    

    Remove the following line of code from your ChildViewController

    self.navigationItem.hidesBackButton = true
    

    And you'll be Ok! If you need to create an action for this transition, I mean whenever the user taps the back button from your ChildViewController. Simply call this method inside of your ChildViewController

     override func didMove(toParentViewController parent: UIViewController?) {
        super.didMove(toParentViewController: parent)
    
        if parent == nil {
    
        } else {
    
        }
    }
    

    Edited:

    ChildViewController

     override func didMove(toParentViewController parent: UIViewController?) {
        super.didMove(toParentViewController: parent)
    
        if parent == nil {
            NotificationCenter.default.post(name: NSNotification.Name.init("Post"), object: nil)
        } else {
    
        }
    
    }
    

    ParentViewController

     override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        NotificationCenter.default.addObserver(self, selector: #selector(self.handler(notification:)), name: NSNotification.Name.init(rawValue: "Post"), object: nil)
    
    }
    
    func handler(notification: Notification) {
    
        let alertController = UIAlertController(title: "Hello", message: nil, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: nil))
        self.present(alertController, animated: true, completion: nil)
    
    }
    

    This is works but with a problem like so:

    Warning: Attempt to present on while a presentation is in progress!

    Therefore I don't recommended. Good luck

    0 讨论(0)
提交回复
热议问题