1
votes

I'm modally presenting a viewController with a semi-transparent view. It's a custom activity indicator. I would like it to cover the view, but leave the navigation bar and tab bar visible and accessible.

The docs, and several SO answers (e.g. Presenting a Modal View Controller hides the Navigation Bar) seem to suggest that presenting the modal onto the navigation controller should achieve this. But when I do it, it shows the tab bar correctly, but covers the navigation bar.

Any ideas? Here is the relevant code:

let spinnerVC = SpinnerViewController()
spinnerVC.modalPresentationStyle = .overCurrentContext
spinnerVC.modalTransitionStyle = .crossDissolve
self.navigationController?.present(spinnerVC, animated: true, completion: nil)
//self.navigationController is definitely not nil
3

3 Answers

3
votes

You can present a your viewcontroller by adding as rootViewController of a navigationController and then present it over the current viewController like this:

let spinnerVC = SpinnerViewController()
let navVC = UINavigationController(rootViewController:spinnerVC)
navVC.modalPresentationStyle = .overCurrentContext
navVC.modalTransitionStyle = .crossDissolve
self.present(navVC, animated: true, completion: nil)
1
votes

you could do it two ways: first one:

Put this code in your parent view

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
}

second one: Add a reference to your invoker in your alert controller in order to hide the bar like this:

weak var invokerView : UIViewController?

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.invokerView?.navigationController?.setNavigationBarHidden(true, animated: animated)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.invokerView?.navigationController?.setNavigationBarHidden(false, animated: animated)
}
0
votes

Don't present it. Add it as a child view controller to the top view controller of your navigation controller and add its view as a subView to the view of the same adjusting the frame.

let spinnerVC = SpinnerViewController()
spinnerVC.view.frame = self.navigationController?.topViewController?.view.bounds
self.navigationController?.topViewController?.addChildViewController(spinnerVC)
self.navigationController?.topViewController?.view.addSubview(spinnerVC.view)