Search code examples
iosswiftuinavigationcontrollerautolayoutuisearchcontroller

Top layout guide moves underneath navigation bar after pushing search results


This one has kept be up a few days. I think the easiest way to illustrate my issue is with this 10 second gif.

Description

GIF

As you can see, when you go back after pushing to a search result, the segmented top bar disappears when you go back, but when I switch to the tab with "Tise" in the header and back, it resets and works properly.

As seen in the below screenshot, my issue is that the top layout guide gets offset underneath the navigation bar, which makes the segmented bar hide underneath it.

enter image description here

Code

My search controller is an extremely normal implementation.

/* Search controller */
let exploreSearchController = StandaloneExploreSearchResultController.initFromStoryboard(type: .top)
searchController = UISearchController(searchResultsController: exploreSearchController)
searchController?.searchResultsUpdater = exploreSearchController
searchController?.delegate = self

searchController?.searchBar.searchBarStyle = .minimal
searchController?.searchBar.isTranslucent = false     
searchController?.searchBar.backgroundColor = .clear
searchController?.hidesNavigationBarDuringPresentation = false
searchController?.dimsBackgroundDuringPresentation = false
searchController?.searchBar.tintColor = #colorLiteral()

navigationItem.titleView = searchController?.searchBar
definesPresentationContext = true

and I push the result controllers in StandaloneExploreSearchResults with

presentingViewController?.navigationController?.pushViewController(viewController, animated: true)

For every new view controller, I update the navigation bar style, which I suspect might be triggering it. If I disable this function, I get different offset bugs, as seen in the following gif.

func updateNavigationBarStyle(viewController: UIViewController) {
    let style = (viewController as? NavigationControllerStyling)?.preferredStyle() ?? .default

    print(#file.components(separatedBy: "/").last!,":",#line,"-",#function, viewController.classForCoder)

    //Showhide
    UIApplication.shared.setStatusBar(hidden: style.statusBar.hidden, style: style.statusBar.style)
    setNavigationBarHidden(style.hidden.hidden, animated: style.hidden.animated)
    navigationBar.setCustomShadow(hidden: style.shadowHidden)

    //Colors
    navigationBar.tintColor = style.tintColor
    navigationBar.barTintColor = style.barTintColor
    navigationBar.backgroundColor = style.backgroundColor

    navigationBar.setBackgroundImage(style.backgroundImage, for: .default)
    navigationBar.titleTextAttributes = style.titleTextAttributes
    navigationBar.isTranslucent = style.translucent

    navigationBar.hairlineImageView?.isHidden = true //Always hide the native shadow
}

enter image description here

Question

Is there a way to either force the auto layout reload that switching tabs triggers (I've tried all the methods I could find with no success). or fix the bug somehow?


Solution

  • Well, that solved it. I guess setting the colors and/or images somehow fiddled with the opaque property.

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        extendedLayoutIncludesOpaqueBars = true
    
    }