UISearchController iOS 11 Customization

IosSwiftUisearchcontrollerIos11

Ios Problem Overview


I had been using the following code prior to iOS 11 to customize the appearance of the UISearchController search bar:

var searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.setDefaultSearchBar()
searchController.searchResultsUpdater = self

if #available(iOS 11.0, *) {
    navigationItem.searchController = searchController
} else {
    tableView.tableHeaderView = searchController.searchBar
}

extension UISearchBar {
    func setDefaultSearchBar() {
        self.tintColor = UIColor.blue
        self.searchBarStyle = .minimal
        self.backgroundImage = UIImage(color: UIColor.clear)
        let searchBarTextField = self.value(forKey: "searchField") as! UITextField
        searchBarTextField.textColor = UIColor.white
        searchBarTextField.tintColor = UIColor.blue
        searchBarTextField = .dark
    }
}

However, the appearance of the search bar fails to update when running the same code on iOS 11.

iOS 10:

enter image description here

iOS 11:

enter image description here

Much of the attention to this question so far has focused on the text color of the search bar. I am looking at more than this - the background color, tint color, the search indicator, clear button color, etc.

Ios Solutions


Solution 1 - Ios

I just found out how to set them: (with some help of Brandon and Krunal, thanks!)

The "Cancel" text:

searchController.searchBar.tintColor = .white

The search icon:

searchController.searchBar.setImage(UIImage(named: "my_search_icon"), for: UISearchBarIcon.search, state: .normal)

The clear icon:

searchController.searchBar.setImage(UIImage(named: "my_search_icon"), for: UISearchBarIcon.clear, state: .normal)

The search text:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSAttributedStringKey.foregroundColor.rawValue: UIColor.white]

enter image description here

The placeholder:

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).attributedPlaceholder = NSAttributedString(string: "placeholder", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])

enter image description here

The white background:

if #available(iOS 11.0, *) {
	let sc = UISearchController(searchResultsController: nil)
	sc.delegate = self
	let scb = sc.searchBar
	scb.tintColor = UIColor.white
	scb.barTintColor = UIColor.white

	if let textfield = scb.value(forKey: "searchField") as? UITextField {
		textfield.textColor = UIColor.blue
		if let backgroundview = textfield.subviews.first {

			// Background color
			backgroundview.backgroundColor = UIColor.white

			// Rounded corner
			backgroundview.layer.cornerRadius = 10;
			backgroundview.clipsToBounds = true;
		}
	}

	if let navigationbar = self.navigationController?.navigationBar {
		navigationbar.barTintColor = UIColor.blue
	}
	navigationItem.searchController = sc
	navigationItem.hidesSearchBarWhenScrolling = false
}

enter image description here

Taken from here.

Solution 2 - Ios

To properly set the text typed into the search bar to white use (when using a dark field color):

searchController.searchBar.barStyle = .black

To set the textfield background color

if #available(iOS 11.0, *) {
    
        if let textfield = searchController.searchBar.value(forKey: "searchField") as? UITextField {
            if let backgroundview = textfield.subviews.first {
                
                // Background color
                backgroundview.backgroundColor = UIColor.white
                
                // Rounded corner
                backgroundview.layer.cornerRadius = 10;
                backgroundview.clipsToBounds = true;
            }
        }
    }

However using something like

textfield.textColor = UIColor.blue

in the above does not seem to work.

Solution 3 - Ios

Try setting the search bar's bar style.

searchController.searchBar.barStyle = UIBarStyleBlack;

image 1

Solution 4 - Ios

Moving the call to setDefaultSearchBar into viewDidAppear should fix this.

Solution 5 - Ios

You need to find the UISearchBar's underlying UITextField and change its text color.

Notice this only have effect when search controller is going to present (UISearchControllerDelegate.willPresentSearchController) or presented.

class ViewController : UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // setup your search controller...
        
        // set search controller's delegate
        navigationItem.searchController?.delegate = self
    }
}

extension ViewController : UISearchControllerDelegate {
    
    func willPresentSearchController(_ searchController: UISearchController) {
        // update text color
        searchController.searchBar.textField?.textColor = .white
    }
}

extension UISearchBar {
    
    var textField: UITextField? {
        for subview in subviews.first?.subviews ?? [] {
            if let textField = subview as? UITextField {
                return textField
            }
        }
        return nil
    }
}

Solution 6 - Ios

    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [NSForegroundColorAttributeName: UIColor.white]

Solution 7 - Ios

Try it: searchController.<YOUR SEARCHBAR>.barStyle = .blackOpaque instead of self.searchBarStyle = .minimal.

Thus:

var searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.setDefaultSearchBar()
//Add this line below
searchController.searchBar.barStyle = .blackOpaque
searchController.searchResultsUpdater = self

if #available(iOS 11.0, *) {
    navigationItem.searchController = searchController
} else {
    tableView.tableHeaderView = searchController.searchBar
}

extension UISearchBar {
    func setDefaultSearchBar() {
        self.tintColor = UIColor.blue
        //Delete this line below
        self.searchBarStyle = .minimal
        self.backgroundImage = UIImage(color: UIColor.clear)
        let searchBarTextField = self.value(forKey: "searchField") as! UITextField
        searchBarTextField.textColor = UIColor.white
        searchBarTextField.tintColor = UIColor.blue
        searchBarTextField = .dark
    }
}

Solution 8 - Ios

If you need to change the background colour of the textField in the searchBar, see my answer here: https://stackoverflow.com/a/46315974/1109892

Solution 9 - Ios

You have to access the UITextField inside the UISearchBar. You can do that by using

let textFieldInsideSearchBar = yourSearchbar.value(forKey: "searchField") as? UITextField

textFieldInsideSearchBar?.textColor = yourcolor

OR

enter image description here

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
QuestionAlexander MacLeodView Question on Stackoverflow
Solution 1 - IosDarkoView Answer on Stackoverflow
Solution 2 - IosZyntxView Answer on Stackoverflow
Solution 3 - IosEddie HsuView Answer on Stackoverflow
Solution 4 - IosRob ZombieView Answer on Stackoverflow
Solution 5 - IosJonnyView Answer on Stackoverflow
Solution 6 - IosIsa MView Answer on Stackoverflow
Solution 7 - IosHoff SilvaView Answer on Stackoverflow
Solution 8 - IosAdam StudenicView Answer on Stackoverflow
Solution 9 - Iosyogesh wadhwaView Answer on Stackoverflow