51

How can I change the font size of UISearchBar ?

1

19 Answers 19

162

I suggest yet a different option for iOS 5.0 and up:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setFont:[UIFont systemFontOfSize:14]];

for iOS 8 (as linked by Mike Gledhill):

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{
            NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:20],
      }];

for iOS 9 and above:

[[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setDefaultTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:20]}];

This way you don't need to mess with enumerating subviews for every search bar in your app.

12
  • 5
    This is the correct answer using apple APIs! Ignore anything else recommended here. Commented Jan 24, 2013 at 0:38
  • 7
    This does not work. For the appearance proxy to work for a particular class/method, the class header file needs a UI_APPEARANCE_SELECTOR for that method. If you open up UITextField, you'll notice that it doesn't have any UI_APPEARANCE_SELECTOR annotations. Commented Mar 18, 2013 at 6:58
  • 3
    This worked for me when I put the line after declaring the UISearchBar and adding it to the table view programatically. If it was beforehand it didn't do anything. I'm not sure how it would work if you're adding search via Interface Builder.
    – Nick
    Commented Nov 4, 2013 at 0:29
  • 1
    This doesn't seem to work with iOS 7+. I think it's because the missing proxy methods :-) Commented Jul 24, 2014 at 14:53
  • 1
    For iOS 11+ simply set UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [...]
    – Evils
    Commented Dec 5, 2018 at 0:43
19

The safe way for performing this operation is as follows:

for(UIView *subView in searchBar.subviews) {
    if ([subView isKindOfClass:[UITextField class]]) {
        UITextField *searchField = (UITextField *)subView;
        searchField.font = [UIFont fontWithName:@"Oswald" size:11];
    }
}

Why is this safer than the accepted answer? Because it doesn't rely on the index of the UITextField staying constant. (it's also a cleaner for loop)

2
  • The only way that this code could break in a future update is if the search bar stops having the UITextField as a subview. But even then, it wouldn't crash. Commented Jan 18, 2013 at 7:19
  • 4
    Doesn't work in iOS 8, because the view hierarchy changed. The text field is no longer at the top level. Since your search is not recursive, it won't find the text field.
    – Pwner
    Commented Dec 3, 2014 at 1:08
16

The accepted answer is not the recommended way of applying font for UISearchBar. Better to avoid this approach and use the answers provided by @rafalkitta or @josema.

But be cautious, this will be applied to all the search bars through out the app. In order to apply this approach to a particular search bar: create a subclass of UISearchBar and set the defaultTextAttributes on the UITextField like below

Swift4:

    let defaultTextAttribs = [NSAttributedStringKey.font.rawValue: UIFont.boldSystemFont(ofSize: 21.0), NSAttributedStringKey.foregroundColor.rawValue:UIColor.red]
    UITextField.appearance(whenContainedInInstancesOf: [CustomSearchBar.self]).defaultTextAttributes = defaultTextAttribs

Obj-C(iOS11)

    UIFont *font = [UIFont boldSystemFontOfSize:21.0];
    UIColor *color = [UIColor redColor];
    NSDictionary * defaultTextAttribs = @{NSFontAttributeName:font, NSForegroundColorAttributeName: color};
    [UITextField appearanceWhenContainedInInstancesOfClasses:@[[CustomSearchBar class]]].defaultTextAttributes = defaultTextAttribs;
1
  • best answer, thanks
    – Mona
    Commented Oct 5, 2021 at 18:22
14

The UISearchBar has a UITextField inside, but there's no property to access it. So, there is no way for doing it in a standard way.

But there is a non-stardard way to workaround it. UISearchBar inherits from UIView, you can access it's subviews using [searchBar subviews]. If you print in the console it's subviews you will see that it have these views.

UISearchBarBackground, UISearchBarTextField.

So, to change the font size you will only need to do that

    UITextField *textField = [[searchBar subviews] objectAtIndex:1];
[textField setFont:[UIFont fontWithName:@"Helvetica" size:40]];

But, if the UISearchBar changes in the future and the textfield isn't in the position 1 anymore, your program will crash, so it's better to check through the subviews the position of the UITextField and then set the font size.

3
  • thanks it worked perfect... i have slightly edited your code and have posted it here as edit
    – pankaj
    Commented Jan 15, 2011 at 4:55
  • 8
    downvoted because it isn't safe and recommended way. Better prefer @josema.vitaminew answer
    – skornos
    Commented Jul 22, 2015 at 7:37
  • Downvoted because there is a new way of since iOS 13 (see above)
    – blackjacx
    Commented Jul 10 at 9:55
12

In swift 2.0 for a search bar created programatically you could do this:

override func layoutSubviews() {
  super.layoutSubviews()

  let textFieldInsideSearchBar = self.searchBar.valueForKey("searchField") as! UITextField
  textFieldInsideSearchBar.font = UIFont.systemFontOfSize(20)
 }

In this case I put the code in a UIView subclass but it will work in other places too (i.e. viewWillAppear from the UIViewController)

12

You can use KVC (key-Value Coding) to get the textfield

UITextField *textField = [self.searchBar valueForKey: @"_searchField"];
[textField setTextColor:[UIColor redColor]];
[textField setFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:17.0]];
4
  • 1
    that is risky for future
    – Hassy
    Commented Dec 13, 2016 at 6:50
  • 1
    It is indeed Hassy. Risk, but it has been working for a couple of years though. Some apps doesn't even live that long. If you use this solution, just make sure you test it before every release of a new iOS. Commented Dec 14, 2016 at 15:43
  • Hey @刘俊利 I'll check it later on, maybe this solution is not valid anymore, it was expected to stop work, almost 5 year since I post it Commented Oct 22, 2019 at 9:28
  • @AdrianoSpadoni I see. Worked like a charm on iOS 7 ~ iOS 12. Thanks
    – 刘俊利
    Commented Oct 24, 2019 at 1:20
9

In swift 3 , you can achieve this by :

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = UIFont(name: "AvenirNextCondensed-Regular", size: 17.0)
1
  • It worked for me. Just that code autocomplete wasn't working when trying .font Commented Jun 7, 2017 at 10:32
6

You shouldn't use private API like in other answers. If you want to customise search bars in whole application, you can use class’s appearance proxy. It allows to modify search bar text attributes, placeholder attributes, cancel button, text field background image, background image etc. Example of use:

if #available(iOS 9.0, *) {
    let searchBarTextAttributes = [
        NSFontAttributeName: UIFont.boldSystemFont(ofSize: 12), 
        NSForegroundColorAttributeName: UIColor.red
    ]
    // Default attributes for search text
    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = searchBarTextAttributes

    // Attributed placeholder string
    UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).attributedPlaceholder = NSAttributedString(string: "Search...", attributes: searchBarTextAttributes)

    // Search bar cancel button
    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(searchBarTextAttributes, for: .normal)
    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Cancel"
}
1
  • 1
    attributedPlaceholder is not needed when defaultTextAttributes is provided. Commented Nov 5, 2019 at 18:58
5

UITextField appearance does not work for UISearchBars created programmatically. You have to use a recursive workaround

- (void)viewDidLoad {
  [super viewDidLoad];
  [self recursivelySkinTextField:self.searchBar];
}

- (void)recursivelySkinTextField:(UIView *)view {
  if (!view.subviews.count) return;

  for (UIView *subview in view.subviews) {
    if ([subview isKindOfClass:[UITextField class]]) {
      UITextField *searchField = (UITextField *)subview;
      searchField.font = [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] font];
      searchField.textColor = [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] textColor];
    }
    [self recursivelySkinTextField:subview];
  }
}
2
  • In general, this is the best solution. It is version agnostic as long as the internal textfield is indeed a UITextField (or subclass) and somewhere in the subview hierarchy. I don't see why you are using UIAppearance though. Why not just set the properties directly?
    – Dima
    Commented May 8, 2014 at 23:53
  • @Dima I'm using UIAppearance because I first set the font and textColor values via appearance proxy, but it's not being picked up by the system when you create your search bar programmatically, that's why I'm using this workaround + values from appearance, so that if I decide to change the values in future, they'd change everywhere throughout the app.
    – Eugene
    Commented May 9, 2014 at 8:30
5

iOS 13+

  searchBar.searchTextField.font = UIFont(name: "YOUR-FONT-NAME", size: 13)
4
  • 1
    Please consider providing some context along with your code. A short explanation about how/why your answer works is recommended.
    – ZGski
    Commented Dec 10, 2019 at 17:18
  • 2
    Uh.. context: this question. How it works: You're going to have to ask Apple. What else do you need @ZGski ? Commented Jan 27, 2020 at 14:15
  • A small explanation of how this works might include: UISearchBar's view hierarchy (or at least the views we care about).
    – ZGski
    Commented Jan 27, 2020 at 15:29
  • Doing this directly after configuration of the searchbar in viewDidLoad creates a searchbar that is way too high. When I change the text afterwards the searchbar is re-layouted to the correct height - any ideas?
    – blackjacx
    Commented Jul 10 at 9:54
3

I wanted to use 'Roboto-Regular' as default font for all the uisearchbars in my project. I made an uisearchbar extension.

extension UISearchBar {
func addRobotoFontToSearchBar(targetSearchBar:UISearchBar?) -> UISearchBar
{
    let textFieldInsideSearchBar = targetSearchBar!.valueForKey("searchField") as! UITextField
    textFieldInsideSearchBar.font = UIFont(name: "Roboto-Regular", size: 15.0)

//UIBarButtons font in searchbar
let uiBarButtonAttributes: NSDictionary = [NSFontAttributeName: UIFont(name: "Roboto-Regular", size: 15.0)!] 
UIBarButtonItem.appearance().setTitleTextAttributes(uiBarButtonAttributes as? [String : AnyObject], forState: UIControlState.Normal)

    return targetSearchBar!
}
}

Usage:

self.sampleSearchBar.addRobotoFontToSearchBar(sampleSearchBar)
3

iOS 13 or later:

if #available(iOS 13.0, *) {
    // set your desired font size
    self.searchBar.searchTextField.font = .systemFont(ofSize: 14.0) 
}
2

Rewrote Eugene's recursive solution in swift - changed the function name to more accurately describe function. For my case, I needed to change the font size. This worked for me.

func findAndSetTextField(view: UIView) {
    if (view.subviews.count == 0){
        return
    }

    for var i = 0; i < view.subviews.count; i++ {
        var subview : UIView = view.subviews[i] as UIView
        if (subview.isKindOfClass(UITextField)){
            var searchField : UITextField = subview as UITextField
            searchField.font = UIFont(name: "Helvetica", size: 19.0)!
         }
         findAndSetTextField(subview)
    }
}
1

Try finding the search bar by its key:

UITextField *searchField = [self.searchDisplayController.searchBar valueForKey:@"_searchField"];
searchField.font = [[UIFont fontWithName:@"Oswald" size:11];
1
  • 1
    This might get your app rejected since you are accessing a private property. The Apple docs specifically says this is not allowed.
    – Widerberg
    Commented May 19, 2014 at 10:22
1

the full code should be below:

for (UIView *v in (SYSTEM_VERSION_LESS_THAN(@"7.0")?searchBar.subviews:[[searchBar.subviews objectAtIndex:0] subviews])) {

    if([v isKindOfClass:[UITextField class]]) {
        UITextField *textField = (UITextField *)v;
        [textField setFont:fREGULAR(@"15.0")];

        return;
    }
}
1

I know this is an old thread, but since iOS 13 UISearchBar has the searchTextField property on which you can set your desired font.

1

If you need a convenient way to change all your application searchbars, here's a simple subclass in Swift 5:

class MySearchBar: UISearchBar {
    override func layoutSubviews() {
        super.layoutSubviews()

        if let textFieldInsideSearchBar = value(forKey: "searchField") as? UITextField {
            textFieldInsideSearchBar.font = UIFont(name: "Oswald-Light", size: 14)
        }
    }
}
0

Add below code where you define or setting up your UISearchBar

Swift4 :

UILabel.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = UIFont.init(name: "Ubuntu-Regular", size: 16)
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = UIFont.init(name: "Ubuntu-Regular", size: 16)

Objective C:

[[UILabel appearanceWhenContainedIn:[UISearchBar class], nil] setFont:[UIFont fontWithName:@"Helvetica" size:12.0]];
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setFont:[UIFont fontWithName:@"Helvetica" size:12.0]];
0

For Swift 4.2+

let defaultTextAttributes = [
    NSAttributedString.Key.font: UIFont.init(name: "Ubuntu-Regular", size: 16),
    NSAttributedString.Key.foregroundColor: UIColor.gray
]
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = defaultTextAttributes

Not the answer you're looking for? Browse other questions tagged or ask your own question.