UIView overlapping UINavigationBar

165 views Asked by At

I am working on an iOS app which presents a viewcontroller modally. This viewcontroller is embedded in a navigation controller. However on iPhone 12, iPhone XR the navigation title, Done and Back button are missing in the navigation bar. I read that if I present a viewcontroller instead of pushing it the navigation item will overriden. I don't want to use push. I need to use present to show the viewcontroller modally.

I found this code with which I can set title dynamically:

self.navigationController?.navigationBar.topItem?.title = "TEST3"

But I can still not see the title when I run the app. I looked into the hierarchy viewer and here is a screenshot where you can see that a random UIView is overlapping my title with "TEST3" in it:

enter image description here

Because of this random UIView I can not see my navigation title. I don't know where this UIView comes from. Does anyone have an idea?

2

There are 2 answers

0
DonMag On

If you present a view controller modally, yes, you only see the very top part of the navigation bar ... until you dismiss the presented controller:

enter image description here

enter image description here

You also cannot interact with the navigation controller or its current view controller while the modal VC is presented.

If you want to keep the navigation bar (with Back and your Done buttons) visible and active, you'll want to add the new controller's view as a subview -- not present it.

0
es1 On

I managed to solve it. In my ViewController I have a static function which instantiates the ViewController which should be presented. In that method I assign the title. It was very strange but only when I set the background of the presented view to a specific colour it started showing the navigation bar with title and button. Here is the code:

static func instantiatedFromDeviceScanHistory(with scanhistoryRecord: ScanHistory, barcode: String, userImage: Any?, calledFromDeviceScanHistory: Bool, hasPackageDescription: Bool) -> UIViewController {
    let viewController = UIStoryboard(name: "MoreInfo", bundle: nil).instantiateViewController(withIdentifier: "MoreInfoViewController") as! MoreInfoViewController
    
    
    viewController.modalPresentationStyle = .fullScreen
    
    viewController.title = "More Info".localized
    viewController.view.backgroundColor = .black // line that made it work
    
    
    let navBar = UINavigationController(rootViewController: viewController)
    navBar.navigationBar.backgroundColor = bgColor
    navBar.navigationBar.tintColor = UIColor.defaultPurple
    navBar.navigationBar.titleTextAttributes = [.foregroundColor : UIColor.defaultPurple]
    navBar.navigationBar.isTranslucent = true
    navBar.navigationBar.shadowImage = UIImage()
    navBar.navigationBar.barTintColor = bgColor
    navBar.navigationBar.topItem?.title = "More Info".localized
    let doneButton = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: viewController, action: #selector(doneClicked))
    doneButton.tintColor = .black
    navBar.navigationBar.topItem?.rightBarButtonItem = doneButton
    navBar.navigationBar.setNeedsLayout()

    return navBar
  }

As you can see I set the background color with:

viewController.view.backgroundColor = .black

And that line solved it for me. Strange but it works now!