Search code examples
iosswiftios9uisearchcontroller

Hiding Cancel button on search bar in UISearchController


I'm trying to hide the Cancel button of the search bar in the UISearchController, but unfortunately setting the following in viewDidLoad() does not work:

override func viewDidLoad() {
    super.viewDidLoad()

    searchResultsTableController = UITableViewController()
    searchResultsTableController.tableView.delegate = self

    searchController = UISearchController(searchResultsController: searchResultsTableController)
    searchController.searchResultsUpdater = self
    searchController.searchBar.sizeToFit()
    searchResultsView.tableHeaderView = searchController.searchBar

    searchController.delegate = self
    searchController.dimsBackgroundDuringPresentation = false
    searchController.searchBar.delegate = self

    searchController.searchBar.searchBarStyle = .Minimal
    searchController.searchBar.showsCancelButton = false

    definesPresentationContext = true
}

I have also tried using the above code in this delegate method:

func didPresentSearchController(searchController: UISearchController) {
    searchController.searchBar.showsCancelButton = false
}

This approach works but will show the Cancel button briefly before hiding it, which is not ideal. Any suggestions?


Solution

  • I ended up subclassing both UISearchBar and UISearchController as suggested:

    CustomSearchBar.swift

    import UIKit
    
    class CustomSearchBar: UISearchBar {
    
        override func layoutSubviews() {
            super.layoutSubviews()
            setShowsCancelButton(false, animated: false)
        }
    }
    

    CustomSearchController.swift

    import UIKit
    
    class CustomSearchController: UISearchController, UISearchBarDelegate {
    
        lazy var _searchBar: CustomSearchBar = {
            [unowned self] in
            let result = CustomSearchBar(frame: CGRectZero)
            result.delegate = self
    
            return result
        }()
    
        override var searchBar: UISearchBar {
            get {
                return _searchBar
            }
        }
    }