Set search bar as a navigation title view

I put a UISearchBar as a UINavigationController titleView. In iOS 11, I get a different navigation bar height 56. (below iOS 11 is 44)

let searchBar = UISearchBar.init(frame: CGRect.init(origin: .zero, size: CGSize.init(width: UIScreen.main.bounds.width, height: (navigationController?.navigationBar.frame.height)!)))
navigationItem.titleView = searchBar

I try to put UIView, UISegmentControl into titleView, but only searchBar get height 56.

I can set searchBar.heightAnchor.constraint(equalToConstant: 44).isActive to make navigation bar back to height 44, but I believe it's not a elegant solution

Is there any reference about this change? Thanks!

Replies

I had the same issue. Navigation bar height grows when you put a search bar in the titleView. It seems that it just isn't a good idea to set the titleView to a UISearchBar anymore. Instead I ended up setting the navigationItem.searchController. Then set searchController.hidesNavigationBarDuringPresentation = YES; With that the behavior is very similar to what you used to get by setting a searchBar in the titleView.

I had the same issue too😠

Can you have UIBarButtonItems alongside the SearchBar using the navigationItem.searchController property?

I believe in iOS 11 UISearchBar now has the height equals to 56, and UINavigationBar uses autolayout to fit its subviews hence it increases the height. If you still want to have UISearchBar as titleView as in pre-iOS 11, I found out the best way to do it is to embed UISearchBar in a custom view, and set this view's height to 44, and assign it to navigationItem.titleView

class SearchBarContainerView: UIView {

    let searchBar: UISearchBar

    var onTextChange: ((IDTMSearchBar) -> Void)?

    init(customSearchBar: UISearchBar) {
        searchBar = customSearchBar
        super.init(frame: CGRect.zero)

        searchBar.delegate = self
        searchBar.placeholder = "Search".localized
        searchBar.barTintColor = UIColor.white
        searchBar.searchBarStyle = .minimal
        searchBar.returnKeyType = .done
        addSubview(searchBar)
    }
    override convenience init(frame: CGRect) {
        self.init(customSearchBar: UISearchBar())
        self.frame = frame
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        searchBar.frame = bounds
    }
}

class MyViewController: UIViewController {

     func setupNavigationBar() {
          let searchBar = UISearchBar()
          let searchBarContainer = SearchBarContainerView(customSearchBar: searchBar)
          searchBarContainer.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44)
          navigationItem.titleView = searchBarContainer
     }
}