swiftuibarbuttonitemuinavigationitemrightbarbuttonitemakswiftslidemenu

UINavigationController acting funny after pushViewController UPDATE 2


I'm having a weird problem, I have a slide menu in my app, for some unknown reason every time that I go from one view to another using the .pushViewController instruction the navigation controller acts funny and it resets my UIBarButtonItems. (They change to their original tintcolor, and the badgeValue disappears).

This is the methods I'm using in the slide menu to do the transition:

func openViewControllerBasedOnIdentifier(_ strIdentifier:String){
    let destViewController : UIViewController = self.storyboard!.instantiateViewController(withIdentifier: strIdentifier)


    let topViewController : UIViewController = self.navigationController!.topViewController!

    if (topViewController.restorationIdentifier! == destViewController.restorationIdentifier!){
        print("Same VC")
    } else {
        var numeroProductos = String(Carrito.numProd)

        self.navigationController!.pushViewController(destViewController, animated: true)


    }
}

and

func slideMenuItemSelectedAtIndex(_ index: Int32) {
    let topViewController: UIViewController = self.navigationController!.topViewController!
    print("View Controller is : \(topViewController) \n", terminator: "")
    switch(index) {
    case 0:
        print("Home\n", terminator: "")

        self.openViewControllerBasedOnIdentifier("Home")

        break

    case 1:
        print("Play\n", terminator: "")

        self.openViewControllerBasedOnIdentifier("MiCuenta")

        break

    case 2:
        print("Play\n", terminator: "")

        self.openViewControllerBasedOnIdentifier("QuienesSomos")

        break

    case 3:
        print("Play\n", terminator: "")

        self.openViewControllerBasedOnIdentifier("NuestraCausa")

        break

    case 4:
        print("Play\n", terminator: "")

        self.openViewControllerBasedOnIdentifier("Contacto")

        break

    case 5:
        print("Play\n", terminator: "")

        self.openViewControllerBasedOnIdentifier("FAQ")

        break

    default:
        print("default\n", terminator: "")
    }
}

According to Apple's own documentation:

A UINavigationItem object manages the buttons and views to be displayed in a UINavigationBar object. When building a navigation interface, each view controller pushed onto the navigation stack must have a UINavigationItem object that contains the buttons and views it wants displayed in the navigation bar. The managing UINavigationController object uses the navigation items of the topmost two view controllers to populate the navigation bar with content.

But this is clearly not happening, the button is there in the interfase builder and it works when I land on that view without using the slide menu, but it disappears when I click any option of my slide menu.

enter image description here

This is the code I have on my viewDidLoad method on that view

override func viewDidLoad() {
    super.viewDidLoad()
    addSlideMenuButton()
    Carrito.numProd = productosCarrito.count
    print(productosCarrito.count)
    var numeroProductos = String(Carrito.numProd)
    navigationItem.rightBarButtonItem?.badgeValue = numeroProductos

}

If I reach the page without using the slidemenu (Like when you segue there after succesfully clearing the login view) the badgeValue is shown properly

enter image description here

But if I use the slide menu this happens

enter image description here

Any ideas on what could be causing this issue?

UPDATE

I discovered something.

If I insert this instruction either in the openVIewControllerBasedOnIdentifier method or in the slideMenuSelectedAtIndex

navigationItem.rightBarButtonItem?.badgeValue = "25"

The badgevalue gets changed to that number just before disappearing, I'm also using this instruction

print("Badge Value:\(navigationItem.rightBarButtonItem?.badgeValue as Any)")

so the value is there because I get this in the debug console:

Badge Value: Optional("40")

But for some unknown reason it disappears

UDATE 2

 self.navigationController!.pushViewController(destViewController, animated: false)

I Discovered that if I turn off animation the badgevalue doesn't disappear, but I need the animation to work too.


Solution

  • I found the solution and it's very simple actually, the avoid this behavior the badgeValue should be set in viewDidLayoutSubViews() instead of viewDidLoad()

    override func viewDidLayoutSubviews() {
        var numeroProductos = String(Carrito.numProd)
        carritoButton.badgeValue = numeroProductos
    }
    

    EDIT MikeMTOL's library is buggy and causes a lot of problems not just this one so for Swift Users I recommend these extensions instead. -> link