Adding a UINavigationController

So after the post the other day I started playing around and I was pretty surprised to find that adding a UINavigationController was that that hard.

I had to obviously create the navigation controller and the AppDelegate seemed like the best place. Using a pretty standard piece of code I was able to instantiate the switchboard controller from the storyboard (yep, still using a storyboard based app) and then set it as the root controller for the navigation controller.

let storyboard = UIStoryboard(name: "Main", bundle: nil)
        if let switchboardVC = storyboard.instantiateViewController(withIdentifier: "SwitchboardViewController") as? SwitchboardViewController {
            
            let navigationController = UINavigationController(rootViewController: switchboardVC)
            window = UIWindow(frame: UIScreen.main.bounds)
            window?.rootViewController = navigationController
            window?.makeKeyAndVisible()

Then it was just a matter of going through each view and adding the relevant menu items to the navigation controller that were being built using a customer banner class currently.

I had an existing presentVC method that handled displaying the views. Without a navigation controller it was just printing the view as the top most view when asked to.

vc.modalPresentationStyle = .fullScreen
vc.modalTransitionStyle = .crossDissolve
topMostController().present(vc, animated: true, completion: nil)

Not that I had a navigation controller though it made more sense to let it control it.

navigationController.pushViewController(vc, animated: true)

Once I made that change the flow just worked as it was the main method handling presenting views.

I spent time creating the nav bar buttons and hooking them up to the existing side menu and everything. I also spent some time looking at what views I could present modally.

Modal views are ones that pop up over the top of the previous views. They basically are their own view controller and are designed for those screens that really have only one function that when done can be closed again. There were a few screens like that I found in the app so I modified the presentVC method to accept an asModal Bool which indicated if I wanted the view to be shown as a standard view or a modal view.

if asModal {
    let modalNavController = UINavigationController(rootViewController: vc)
    modalNavController.modalPresentationStyle = .popover
    modalNavController.modalTransitionStyle = .coverVertical

    // Add a dismiss button to the presented view controller
    vc.navigationItem.leftBarButtonItem = UIBarButtonItem(
        barButtonSystemItem: .close,
        target: self,
        action: #selector(dismissModal)
    )

    navigationController.present(modalNavController, animated: true, completion: nil)
} else {
    navigationController.pushViewController(vc, animated: true)
}

When I started using the modal views I ran into a few issues.

  1. Using a modal view meant that when the view was activated from the side menu, the menu did not get closed which meant when the modal was dismissed the menu was still there.
  2. When updating the theme in the new Settings modal, the theme only updated the modal view and no other part of the app.

It took me a while but in the end I solved nothing issues using notifications. When The modal was activated, send a notification to close the menu. Then in the view itself I could get that notification and run the code to close the menu. The theme was the exact same thing. Because the modal was in its only navigation structure now, updating the theme only affected the current view so I just fired off a notification that was accepted by the main switchboard view which then updated the theme as well.

It’s been a pretty big learning curve but a heck of a lot of fun. I’ll likely push the UIViewController changes out to test flight soon and all going well release it to the store in a few days.

Next? I’ve been playing around with the main app design. Figured out how to convert SVG graphics to Swift code which obviously makes programatically changing UI element colours way easier and saves a lot of space not having to have seperate image files.

Similar Posts