25

I want to place a search bar in the new navigation bar with the new iOS 11 large titles. However, the color of the search bar is automatically applied by iOS and I can't change it.

if #available(iOS 11.0, *) {
    let sc = UISearchController(searchResultsController: nil)
    navigationItem.searchController = sc
    navigationItem.hidesSearchBarWhenScrolling = false
}

The search bar get's a deep blue background, but I just want to change it to white.

enter image description here

Setting the background color results in this:

navigationItem.searchController?.searchBar.backgroundColor = UIColor.white

enter image description here

I have tried also setScopeBarButtonBackgroundImage and setBackgroundImage on the search bar but everything looks totally weird.

Also when I trigger the search by tapping on the search bar, it switches to a mode with the cancel button on the right side. ("Abbrechen" in German)

enter image description here

And the "Abbrechen" text color also can't be changed. (need it also white)

Any help is appreciated.

Edit: As requested, here the code for the navigation bar styling:

self.navigationBar.tintColor = UIColor.myWhite
self.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.myWhite, NSAttributedStringKey.font: UIFont.myNavigationBarTitle()]
self.navigationBar.barTintColor = UIColor.myTint

if #available(iOS 11.0, *) {
    self.navigationBar.prefersLargeTitles = true
    self.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.myWhite, NSAttributedStringKey.font: UIFont.myNavigationBarLargeTitle()]
}

Current outcome: I have used Krunals idea to set the color of the search bar background but then the rounded corners are lost. After re-setting the rounded corners the animation of the search bar seems to be broken.

enter image description here

So still no satisfactory solution. Seems that the search bar when embedded into the navigation bar in iOS 11 is not possible to customize. Meanwhile it would be enough for me to just change the color of the placeholder text, but even this seems not to be possible. (I have tried multiple approaches from StackOverflow - doesn't work)

Darko
  • 9,655
  • 9
  • 36
  • 48

7 Answers7

21

Now it's what you want...

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

}

Result:

enter image description here

enter image description here


With Rounded corner:
Animation with rounded corner is also working fine.

enter image description here

Darko
  • 9,655
  • 9
  • 36
  • 48
Krunal
  • 77,632
  • 48
  • 245
  • 261
  • Yes, thirst success, thanks! The rounded edges would also be possible over view.layer I suppose. Accomplish this also and I will mark it as answered, for others to find this. The inside knowledge about the inner workings is also not the most preferable way to achieve it, but if that's the only way... – Darko Sep 01 '17 at 12:19
  • I have tried to set the rounded layers and it works. But then the animation when scrolling the search bar looks strange. Overall all of this seems like a hack and is not really good working. – Darko Sep 01 '17 at 19:17
  • Yes, this is now working really fine Krunal. The missing piece was `backgroundview.clipsToBounds = true`. Just one final thing: the rounded corners need to have the value 10. Otherwise you will see those tiny white areas in each corners of the searchbar. And 10 resembles also exactly how the Apple-style looks like. So please edit to 10 and I will mark your post as answered. Btw.: this is still kinda "hacky" way to fix this as it could not work in iOS 12 anymore. But if hacky is currently the only way to do this then your answer is legit. Thanks for your help. – Darko Sep 16 '17 at 05:17
  • @Krunal @Darko Is there a way to keep the `UISearchBar` Inside the Navigation bar and also get rid the Animation? – Mario Galván Sep 22 '17 at 17:23
  • @MarioGalván Unable to get your concern, Can you please provide more detail, what do you want? – Krunal Sep 24 '17 at 12:47
  • textfield.textColor why text alway is black ? – iHTCboy Oct 15 '17 at 11:34
  • How do you change the placeholder text color with this solution? It looks like the textfield attributedPlaceholder doesn't work. – Renato Nov 07 '17 at 20:23
  • In order to change background color of the text field. make sure searchBar.searchBarStyle = UISearchBarStyleMinimal; – Delorean Nov 28 '17 at 12:44
  • @Krunal Have you managed to get this working on iOS 11.2. For us on that, the text in the search bar is white and so invisible to the user. – simonthumper Jan 17 '18 at 16:11
  • @simonthumper - Yes it's working in 11.2 also. Raise a new question with your code and share it to me. I'll surely help you to solve it. – Krunal Jan 17 '18 at 16:33
  • @Darko See this answer https://stackoverflow.com/questions/45997996/ios-11-uisearchbar-in-uinavigationbar/58427476#58427476 – Ashu Oct 17 '19 at 07:48
4

I changed the background of the text field with this code inside AppDelegate.

Swift 4

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        //background color of text field
         UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).backgroundColor = .cyan
        
        }

This is the result

example used to change the background to cyan color

Community
  • 1
  • 1
Maruta
  • 1,063
  • 11
  • 24
3

This should work for you

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

            if let navigationbar = self.navigationController?.navigationBar {
                //navigationbar.tintColor = UIColor.green
                //navigationbar.backgroundColor = UIColor.yellow
                navigationbar.barTintColor = UIColor.blue
            }

            navigationController?.navigationBar.tintColor = UIColor.green
            navigationItem.searchController = sc
            navigationItem.hidesSearchBarWhenScrolling = false
        }
}


Result:

enter image description here

enter image description here

Krunal
  • 77,632
  • 48
  • 245
  • 261
3

Objective C

if (@available(iOS 11.0, *)) {
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchController.searchResultsUpdater = self;
    self.searchController.searchBar.delegate = self;
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.navigationItem.searchController=self.searchController;
    self.navigationItem.hidesSearchBarWhenScrolling=NO;
    self.searchController.searchBar.searchBarStyle = UISearchBarStyleProminent;
    self.searchController.searchBar.showsBookmarkButton = NO;
    self.searchController.searchBar.placeholder = @"Search";
    self.searchController.searchBar.tintColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
    self.searchController.searchBar.barTintColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1];
    UITextField *txfSearchField = [self.searchController.searchBar valueForKey:@"_searchField"];
    txfSearchField.tintColor=[UIColor colorWithRed:21/255.0 green:157/255.0 blue:130/255.0 alpha:1];
    txfSearchField.textColor=[UIColor colorWithRed:1 green:1 blue:1 alpha:1];
    txfSearchField.backgroundColor=[UIColor whiteColor];
    UIView *backgroundview= [[txfSearchField subviews]firstObject ];
    backgroundview.backgroundColor=[UIColor whiteColor];
    // Rounded corner
    backgroundview.layer.cornerRadius = 8;
    backgroundview.clipsToBounds = true;
}
nkitku
  • 4,779
  • 1
  • 31
  • 27
  • 2
    Welcome to Stack Overflow! Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation [would greatly improve](//meta.stackexchange.com/q/114762) its long-term value by showing *why* this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Toby Speight Oct 16 '17 at 12:57
1

This is the code I used to make the search bar white:

if let textfield = searchController.searchBar.value(forKey: "searchField") as? UITextField {
            if let backgroundview = textfield.subviews.first {
                backgroundview.backgroundColor = UIColor.init(white: 1, alpha: 1)
                backgroundview.layer.cornerRadius = 10
                backgroundview.clipsToBounds = true
            }
        }

enter image description here

iOS_Mouse
  • 754
  • 7
  • 13
  • How did you get the searchbar below the large title? – Helge Becker Nov 06 '18 at 16:02
  • The searchbar is placed below the large title by default if you add a search controller to the navigation bar. In code I created a search controller in the ViewDidLoad-- let controller = UISearchController(searchResultsController: nil) -- followed by setting up all the features for "controller". Then I added the search controller to the navigation -- navigationItem.searchController = controller -- followed by some more setup – iOS_Mouse Nov 06 '18 at 16:38
  • 1
    That's not white, it's a very light gray – Jonathan Cabrera Dec 20 '18 at 22:46
1

Tested on ios 13

Perfect white background on searchBar

func setupSearchbarController(){
    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.white
            textfield.backgroundColor = UIColor.white
            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 = AppColor.themeColor
        }
        navigationItem.searchController = sc
        navigationItem.hidesSearchBarWhenScrolling = false
    }
}
Ashu
  • 3,373
  • 38
  • 34
  • Hi I have tested this code and it works great on iOS 13 devices but seems to have problems in iOS 12. Is this the case with anyone? – Satsuki Mar 30 '20 at 14:08
0

Try this code,

UITextField *txfSearchField = [_searchBar valueForKey:@"_searchField"];
txfSearchField.backgroundColor = [UIColor redColor];
AshokPolu
  • 645
  • 5
  • 12
  • `if let textField = navigationItem.searchController?.searchBar.value(forKey: "_searchField") as? UITextField { textField.backgroundColor = UIColor.white }` - this does not work. – Darko Sep 01 '17 at 10:32