In the final viewcontroller of my application, I use popToMainViewController to go back to the first view controller. When the method is called, customized rightBarButtonItems is not displayed. rightBarButtonItems work as expected when the mainViewController gets displayed for the first time after the application is started.

extension UINavigationController {
    func popToMainViewController(animated: Bool) {
        if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
           let rootController = windowScene.windows.first?.rootViewController as? UINavigationController,
           let mainViewController = rootController.viewControllers.first(where: { $0 is MainViewController }) {
            popToViewController(mainViewController, animated: animated)
        }
    }
}

I use this code to go back to my MainViewController. The reason why I use this function is because I use customized LaunchScreen, MainViewController is the second viewcontroller in the navigation controller.

I call the method in

    @objc func callMainVC() {
        audioPlayerManager.stop()
        self.navigationController?.popToMainViewController(animated: true)
    }

In my MainViewController,

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configureSettingBtn()
        configureNavBarItems()
    }

func configureSettingBtn() {
        let settingImage = UIImage(named: "settingIcon")
        let settingBtn = UIButton()
        settingBtn.setImage(settingImage, for: .normal)
        settingBtn.addTarget(self, action: #selector(settingApp), for: .touchUpInside)
        let setting = UIBarButtonItem(customView: settingBtn)
        
        self.navigationItem.rightBarButtonItems = [setting]
    }

private func configureNavBarItems() {
        print("configuring nav bar items")
        let spacer = createSpacer()
        
        let infoImage = UIImage(named: "infoIcon")
        let infoBtn = UIButton()
        infoBtn.setImage(infoImage, for: .normal)
        infoBtn.addTarget(self, action: #selector(guide), for: .touchUpInside)
        let info = UIBarButtonItem(customView: infoBtn)

        navigationItem.rightBarButtonItems?.append(contentsOf: [spacer, info])
    }
    
    @objc func guide() {
        let componentPositions: [CGRect] = [playerButton.frame, refereeButton.frame, hostButton.frame, gameWalkerImage.frame]
        let layerList: [CALayer] = [playerButton.layer, refereeButton.layer, hostButton.layer]
        let explanationTexts = ["Join as a team member", "Allocate points and manage individual games", "Organize and oversee the entire event"]
        
        let overlayViewController = MainOverlayViewController()
        overlayViewController.modalPresentationStyle = .overFullScreen // Present it as overlay
        overlayViewController.configureGuide(componentPositions, layerList, explanationTexts)
        
        present(overlayViewController, animated: true, completion: nil)
    }
    

These are my setUp for the navigation controller. hidesBackButton is set to true

MAINVIEWCONTROLLER IMAGE The screen should look like this, but when the popToMainViewController is called, Malfunctioning MainViewController The NavBarButtons are not displayed.

I tried Xcode menu Debug > View Debugging > Show View Frames, and I think navigationController does not exist. But I don't know how to resolve this problem show view frames

I tried

self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.isNavigationHidden = false
self.navigationController?.setNavigationControllerHidden(false, animated: false)

Also tried debugging and confirmed that viewWillDisappear and methods in viewWillDisappear is called everytime I access MainViewController. But When I call popToMainViewController, the customized navigation Item is not shown, and that occurs the same in following viewcontrollers.

I printed self.navigationController in viewWillAppear of the MainViewController. The same navigationController gets printed everytime I move to the MainViewController. Even when I call the popToMainViewController method, the same navigationController gets printed, but not displayed.

1

There are 1 answers

6
Duncan C On

I'm not sure if this is the problem, but you are setting up your navigation items in viewWillAppear. View controllers on a navigation stack stick around, and viewWillAppear gets called again when you pop back to them. It looks to me like your configureNavBarItems() function is appending items to your rightBarButtonItems. Thus, when you go back to your MainViewController, you'll have duplicate rightBarButtonItems.

Try moving your navigation bar setup code to viewDidLoad rather than viewWillAppear.