Get search bar in navigation bar in Swift

IosXcodeSwiftUinavigationbarUisearchbar

Ios Problem Overview


So I've tried everything trying to get a search bar into the navigation bar in Swift. But sadly I haven't gotten it working, just yet...

For those of you who don't know what I'm talking about, I'm trying to do something like this

enter image description here

Note the search bar in the navigation bar. So here's what I'm currently using

self.searchDisplayController?.displaysSearchBarInNavigationBar = true

I popped that in my viewDidLoad, and then when I load up the app I'm presented with, just an empty navigation bar.... :( Any ideas?

Ios Solutions


Solution 1 - Ios

Try this

let leftNavBarButton = UIBarButtonItem(customView:Yoursearchbar)
  self.navigationItem.leftBarButtonItem = leftNavBarButton

Update

You keep a lazy UISearchBar property

lazy   var searchBar:UISearchBar = UISearchBar(frame: CGRectMake(0, 0, 200, 20))

In viewDidLoad

searchBar.placeholder = "Your placeholder"
var leftNavBarButton = UIBarButtonItem(customView:searchBar)
self.navigationItem.leftBarButtonItem = leftNavBarButton

If you want to use storyboard just drag your searchbar as a outlet,then replace the lazy property with your outlet searchbar

Solution 2 - Ios

    // create the search bar programatically since you won't be
    // able to drag one onto the navigation bar
    searchBar = UISearchBar()
    searchBar.sizeToFit()

    // the UIViewController comes with a navigationItem property
    // this will automatically be initialized for you if when the
    // view controller is added to a navigation controller's stack
    // you just need to set the titleView to be the search bar
    navigationItem.titleView = searchBar

Solution 3 - Ios

Swift 5, XCode 11, Storyboard way so you can easily add all the search bar attributes through the storyboard and you have less code in your view controller class.

1.) Add your search bar view as external view in viewcontroller.

enter image description here

2.) Connect searchBarView to you viewcontroller.

enter image description here

3.) Add your searchBarView to your navigationBar title item.

navigationItem.titleView = searchBarView

Result:

enter image description here

Solution 4 - Ios

In your view controller:

lazy var searchBar = UISearchBar(frame: CGRectZero)

override func viewDidLoad() {
    super.viewDidLoad()
    
    searchBar.placeholder = "Search"
    
    navigationItem.titleView = searchBar
}

Doing it this way, by setting the navigationItem.titleView, the search bar is automatically centered across the iPhone and iPad devices. Note: only tested with v8.4 and v9.0

for SWIFT 3

lazy var searchBar = UISearchBar(frame: CGRect.zero)

Solution 5 - Ios

In 2019, you should use UISearchController.

override func viewDidLoad() {
    super.viewDidLoad()
    
    let searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self.viewModel
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchBar.placeholder = "Search artists"
    self.navigationItem.searchController = searchController
    self.definesPresentationContext = true
}

And some class should conform to UISearchResultsUpdating. I usually add this as extension to my ViewModel.

extension ArtistSearchViewModel: UISearchResultsUpdating {

func updateSearchResults(for searchController: UISearchController) {
    print("Searching with: " + (searchController.searchBar.text ?? ""))
    let searchText = (searchController.searchBar.text ?? "")
    self.currentSearchText = searchText
    search()
    }
}

This will spawn something like this:

search bar

Solution 6 - Ios

For iOS 11 and above

navigationItem.searchController = searchController

enter image description here

For iOS 10 and below

navigationItem.titleView = searchController.searchBar;

enter image description here

or you can assign it as leftBarButtonItem as described in this answer

Solution 7 - Ios

    let searchBar = UISearchBar()
    searchBar.sizeToFit()
    searchBar.placeholder = ""
    self.navigationController?.navigationBar.topItem?.titleView = searchBar

Solution 8 - Ios

For Swift 5 or letter

also, you can use this code. Fully Programmatically

import UIKit

class SearchTableViewController: UITableViewController {

private lazy var searchController: UISearchController = {
    let sc = UISearchController(searchResultsController: nil)
    sc.searchResultsUpdater = self
    sc.delegate = self
    sc.obscuresBackgroundDuringPresentation = false
    sc.searchBar.placeholder = "Enter A Compiny Name Or Symbole"
    sc.searchBar.autocapitalizationType = .allCharacters
    return sc
}()

override func viewDidLoad() {
    super.viewDidLoad()
    setupNavigationBar()
}

   private func setupNavigationBar() {
       navigationItem.searchController = searchController
   }

 }

// MARK: - UISearchResult Updating and UISearchControllerDelegate  Extension
  extension SearchTableViewController: UISearchResultsUpdating, UISearchControllerDelegate {
    func updateSearchResults(for searchController: UISearchController) {
    
    }
 }

After Clicking Search 

After Clicking Cancel Button In Search 

Solution 9 - Ios

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    
    searchBar.endEditing(true)
    searchBar.text = nil
    print("## search btn clicked : \(searchBar.text ?? "")")
} 

Solution 10 - Ios

For Swift 4 and 5.

let searchBar = UISearchBar()
self.navigationItem.titleView = searchBar

let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: nil)

cancelButton.tintColor = #colorLiteral

searchBar.tintColor = #colorLiteral

self.navigationItem.rightBarButtonItem = cancelButton

Solution 11 - Ios

Setting SearchBar as titleView, changes height of navigationBar to 56. To fix this, you can embed searchBar in view and set that as titleView.

    var offset: CGFloat = 20
    
    // If VC is pushed, back button should be visible
    if navigationController?.navigationBar.backItem != nil {
        offset = 40
    }
    
    let customFrame = CGRect(x: 0, y: 0, width: view.frame.size.width - offset, height: 44.0)
    let searchBarContainer = UIView(frame: customFrame)
    searchBar = UISearchBar(frame: customFrame)
    searchBarContainer.addSubview(searchBar)
    navigationItem.titleView = searchBarContainer

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionidrisView Question on Stackoverflow
Solution 1 - IosLeoView Answer on Stackoverflow
Solution 2 - Iosantonio081014View Answer on Stackoverflow
Solution 3 - IosEgzon P.View Answer on Stackoverflow
Solution 4 - IosiAmcRView Answer on Stackoverflow
Solution 5 - IosMartin BergerView Answer on Stackoverflow
Solution 6 - IosHusamView Answer on Stackoverflow
Solution 7 - IosluhuiyaView Answer on Stackoverflow
Solution 8 - IosChandanView Answer on Stackoverflow
Solution 9 - IosSami YousifView Answer on Stackoverflow
Solution 10 - IosimpalairisView Answer on Stackoverflow
Solution 11 - IosArijanView Answer on Stackoverflow