Search code examples
swiftuinavigationcontrolleruisearchcontroller

Use background image on UISearchController iOS 11


I'm implementing an UISearchController to my UITableView but I'm struggling with the customization for iOS 11. My navigation bar is using a gradient image background that I want the search controller to match, but I haven't found a way to set the background image for UISearchController. It works perfectly on UISearchController as a TableHeaderView, but in iOS 11 barely any customization is passed on.

Current outcome:

Current outcome

Desired outcome:

Desired outcome

This is the code I'm using: (called on viewDidLoad)

private func setupSearchController() {

    let searchController = UISearchController(searchResultsController: nil)

    // Convert CAGradientLayer to UIImage
    let gradient = Color.blue.gradient
    gradient.frame = searchController.searchBar.bounds
    UIGraphicsBeginImageContext(gradient.bounds.size)
    gradient.render(in: UIGraphicsGetCurrentContext()!)
    let gradientImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    // Setup the Search Controller
    searchController.searchBar.backgroundImage = gradientImage
    searchController.searchBar.isTranslucent = false
    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = false
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchBar.placeholder = "Search by transaction name"
    searchController.searchBar.tintColor = Color.custom(hexString: "FAFAFA", alpha: 1).value
    definesPresentationContext = true
    searchController.searchBar.delegate = self

    // Implement Search Controller
    if #available(iOS 11.0, *) {
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
        navigationController?.navigationBar.setBackgroundImage(gradientImage, for: .default)
    } else {
        tableView.tableHeaderView = searchController.searchBar
    }

}

Solution

  • Thanks to Krunal's answer I was able to find a decent solution after searching for quite some time.

    This is how I came about implementing the background-image for iOS 11:

        // Implement Search Controller
        if #available(iOS 11.0, *) {
            if let navigationBar = self.navigationController?.navigationBar {
                navigationBar.barTintColor = UIColor(patternImage: gradientImage!)
            }
            if let textField = searchController.searchBar.value(forKey: "searchField") as? UITextField {
                if let backgroundview = textField.subviews.first {
                    backgroundview.backgroundColor = UIColor.white
                    backgroundview.layer.cornerRadius = 10;
                    backgroundview.clipsToBounds = true;
    
                }
            }
            navigationItem.searchController = searchController
            navigationItem.hidesSearchBarWhenScrolling = false
        } else {
            tableView.tableHeaderView = searchController.searchBar
        }