Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I completely override the navbar's back button action?

Basically my issue is that I'm trying to create a drawer since iOS/Swift doesn't seem to have a native object for this. For reasons I can't recall, I decided to go with a navigation controller for this, thinking I could just override the back button(s) and their actions to turn this nav bar into a drawer. While I've changed the image/text of the back button successfully to look like a "burger" (drawer icon), I can't figure out how to successfully stop the button from taking us back, and instead have it just open/close my drawer.

Any advice appreciated, including suggestions to take an entirely different approach to creating this.

The following is the controller for the page which has the back button i'm trying to override. You can see in viewDidLoad() I call prepareDrawerPage(), which is a helper I have in another file. This definition can also be seen below.

class CreateListingController: UIViewController {
    let DRAWER_OPEN = CGFloat(0)
    var DRAWER_CLOSED: CGFloat = 0  // -1 * width of drawer

    @IBOutlet var navItem: UINavigationItem!
    @IBOutlet var drawerView: UIView!
    @IBOutlet var drawerViewLead: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        DRAWER_CLOSED = UIScreen.main.bounds.width * -1 * drawerViewLead.multiplier
        drawerViewLead.constant = DRAWER_CLOSED
        prepareDrawerPage(controller: self, title: "PBX - Create a Listing")
    }


    @IBAction func flipMenu(_ sender: UIBarButtonItem) {
        if (drawerViewLead.constant == DRAWER_OPEN){
            drawerViewLead.constant = DRAWER_CLOSED
            UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseOut, animations: {
                self.view.layoutIfNeeded()
            })
        } else {
            drawerViewLead.constant = DRAWER_OPEN
            UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }

}

prepareDrawerPage():

func prepareDrawerPage(controller: UIViewController, title: String) {
    let blank = UIImage()
    controller.navigationController?.navigationBar.backIndicatorImage = blank
    controller.navigationController?.navigationBar.backIndicatorTransitionMaskImage = blank
    controller.title = title
}

The above approach works fine on the home page, where we haven't used the navigation bar yet. However, once we click to the create listing page, the button still takes us back home when clicked despite having linked an action between the BarButtonItem (back button) and CreateListingController (flipMenu function).

like image 583
zbbz Avatar asked Jan 26 '26 22:01

zbbz


1 Answers

You can add a custom button on the navigation bar.

override func viewDidLoad() {
    ...
    self.navigationItem.hidesBackButton = true
    let newBackButton = UIBarButtonItem(image: YourImage, style: .plain, target: self, action: #selector(back(sender:)))
    self.navigationItem.leftBarButtonItem = newBackButton
    ...
}

@objc func back(sender: UIBarButtonItem) {
    // Perform your custom actions
    // ...
    // Go back to the previous ViewController
    // self.navigationController?.popViewController(animated: true)
}
like image 54
ovo Avatar answered Jan 29 '26 12:01

ovo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!