13
votes

I’m attaching a UISearchController to the navigationItem.searchController on iOS 13. This works fine: I can use the nice iOS 13-style search bar.

However, I’d like see the large titles and searchBar by default.

I set navigationItem.hidesSearchBarWhenScrolling = false because I want to see the search permanently on my screen, but the search bar replace large titles by default.

Does anyone know how is this is possible?

Check this out

navigationItem.searchController = UISearchController(searchResultsController: nil)
navigationItem.hidesSearchBarWhenScrolling = false

This is how it looks actually This is how it looks actually

This is how I need to implement(large title and search bar both visible) This is how I need to implement(large title and search bar both visible)

4
Did you find a solution?amone

4 Answers

3
votes

For me it worked after adding following lines in the viewDidLoad() method :

searchController.hidesNavigationBarDuringPresentation = true navigationController?.navigationBar.prefersLargeTitles = true navigationController!.navigationBar.sizeToFit()

1
votes

Try this, working fine in my side

    private var search = UISearchController(searchResultsController: nil)

    override func viewDidLoad() {
        super.viewDidLoad()
        search.searchBar.delegate = self
        search.searchBar.sizeToFit()
        search.obscuresBackgroundDuringPresentation = false
        search.hidesNavigationBarDuringPresentation = true
        self.definesPresentationContext = true
        search.searchBar.placeholder = "Search here"
        self.navigationItem.searchController = search
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationItem.hidesSearchBarWhenScrolling = false
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationItem.hidesSearchBarWhenScrolling = true
    }

For large navigation bar use this

For full application navigation bar support please add this extension inside your code.

import UIKit
extension UIViewController {


    open func showNavigationBar(_ large: Bool,
                                _ animated: Bool,
                                titleColor: UIColor,
                                barTintColor: UIColor,
                                fontSize: CGFloat) {

        navigationController?.navigationBar.barTintColor = barTintColor
        navigationController?.navigationBar.backgroundColor = barTintColor
        navigationController?.navigationBar.isTranslucent = true
        self.navigationController?.setNavigationBarHidden(false, animated: animated)
        if large {
            self.navigationController?.navigationBar.prefersLargeTitles = true
            if #available(iOS 13.0, *) {
                let appearance = UINavigationBarAppearance()
                appearance.backgroundColor = barTintColor
                appearance.titleTextAttributes = [.foregroundColor: titleColor]
                appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor,
                                                       NSAttributedString.Key.font: UIFont(resource: R.font.robotoMedium, size: fontSize)!]

                navigationController?.navigationBar.standardAppearance = appearance
                navigationController?.navigationBar.compactAppearance = appearance
                navigationController?.navigationBar.scrollEdgeAppearance = appearance
            } else {
                self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor,
                                                                                     NSAttributedString.Key.font: UIFont(resource: R.font.robotoMedium, size: fontSize)!]
            }
        } else {
            self.navigationController?.navigationBar.prefersLargeTitles = false
            self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor,
                                                                            NSAttributedString.Key.font: UIFont(resource: R.font.robotoMedium, size: 20.0)!]
        }
    }
}

And Then call this method simply

self.showNavigationBar(true, true, titleColor: UIColor.blue, barTintColor: UIColor.red, fontSize: 32.0)

If then Also not work then use this

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        search.searchBar.becomeFirstResponder()
    }

one more solution is that add one UIView with height 0 in storyboard and set-top with safe area and bottom with UIScrollView/UICollectionView/UITableVIew or something else scrollable view and Remove Direct Constraint between TopSafeArea And ScrollableView Top. I know maybe this is not a solution but I did in a storyboard.

1
votes

Okay so I've been trying to achieve the same thing all day long for my app as well and I finally did it.

I wanted to add a searchBar on a UITableViewController and I did it this way.

    let searchController: UISearchController = {

    let searchController = UISearchController(searchResultsController: nil)

    searchController.searchBar.placeholder = "New Search"
    searchController.searchBar.searchBarStyle = .minimal
    searchController.dimsBackgroundDuringPresentation = false
    searchController.definesPresentationContext = true

   return searchController
}()

You first create a new UISearchController using a closure, that way you are able to use it globally in your code and customize it easier in the future.

Afterwards in viewDidLoad, you set the searchSontroller.searchResultsUpdater = self and the navigationItem.searchController = searchController.

For me it works perfectly after a lot of trial and error since I'm doing everything programmatically.

0
votes

This code should work

class NavigationController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        createCustomTabBar()
    }

    func createCustomTabBar() {
    
        let firstVC = UINavigationController(rootViewController: HomeVC())
        firstVC.title = "Home"
        firstVC.tabBarItem.image = UIImage(systemName: "house.fill")

        viewControllers = [firstVC]
    }

class HomeVC: UIViewController {
    let searchController = UISearchController(searchResultsController: nil)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Home"
        navigationItem.searchController = searchController
    }
}

NavigationBar+SearchBar