51

How can I change the font size of UISearchBar ?

trapper
  • 11,716
  • 7
  • 38
  • 82
pankaj
  • 7,878
  • 16
  • 69
  • 115
  • Check this question : http://stackoverflow.com/questions/19161652/change-the-font-size-and-font-style-of-uisearchbar-ios-7 – Axel Guilmin Nov 11 '14 at 11:06

19 Answers19

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.

Pablo Marrufo
  • 855
  • 1
  • 8
  • 17
José Manuel Sánchez
  • 5,215
  • 2
  • 31
  • 24
  • 5
    This is the correct answer using apple APIs! Ignore anything else recommended here. – Yariv Nissim Jan 24 '13 at 00: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. – Bart Vandendriessche Mar 18 '13 at 06:58
  • Well, it certainly works, thought it's true that UITextField doesn't declare that annotation. Maybe they forgot to add the annotation; it should be there anyway. – José Manuel Sánchez Mar 20 '13 at 12:02
  • In what circumstances are you finding that this works? Unfortunately, it refuses to for me with iOS 6.1 Simulator, at the very least. – Rob Rix Jul 12 '13 at 16:43
  • This actually does work for me in the iOS 6.1 simulator, nice! – qix Sep 03 '13 at 08:09
  • 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 Nov 04 '13 at 00:29
  • If created programatically, I needed to use the recursive solution outlined by @Eugene – Willster Apr 16 '14 at 17:02
  • UITextField does not implement UIAppearance proxy. Forget about it. – pronebird Jun 04 '14 at 18:19
  • 1
    This doesn't seem to work with iOS 7+. I think it's because the missing proxy methods :-) – Tatarasanu Victor Jul 24 '14 at 14:53
  • Has anyone been able to use this in conjunction with UIContentSizeCategoryDidChangeNotification to update the font size based on the user changing the Text Size option in Settings? This sets the font initially, but calling this again when the Text Size has been updated does not work for me. – groomsy Aug 05 '14 at 19:55
  • Didn't work consistantly with me on iOS8.1. Have a look at the "appearanceWhenContainedIn" suggestion here, which did work each time: http://stackoverflow.com/questions/19161652/change-the-font-size-and-font-style-of-uisearchbar-ios-7 – Mike Gledhill Feb 06 '15 at 10:28
  • 1
    For iOS 11+ simply set `UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [...]` – Evils Dec 05 '18 at 00: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)

Gavin Miller
  • 43,168
  • 21
  • 122
  • 188
  • 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. – Nicolas Miari Jan 18 '13 at 07: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 Dec 03 '14 at 01: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;
Rishi
  • 743
  • 8
  • 17
15

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.

Bruno Domingues
  • 1,017
  • 9
  • 12
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]];
webo80
  • 3,365
  • 5
  • 35
  • 52
Adriano Spadoni
  • 4,540
  • 1
  • 25
  • 25
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)

Ciprian Rarau
  • 3,040
  • 1
  • 30
  • 27
9

In swift 3 , you can achieve this by :

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = UIFont(name: "AvenirNextCondensed-Regular", size: 17.0)
Ashildr
  • 1,783
  • 3
  • 16
  • 25
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"
}
rafalkitta
  • 492
  • 6
  • 9
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];
  }
}
Eugene
  • 10,006
  • 4
  • 37
  • 55
  • 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 May 08 '14 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 May 09 '14 at 08:30
4

iOS 13+

  searchBar.searchTextField.font = UIFont(name: "YOUR-FONT-NAME", size: 13)
Bob Gilmore
  • 12,608
  • 13
  • 46
  • 53
  • 1
    Please consider providing some context along with your code. A short explanation about how/why your answer works is recommended. – ZGski Dec 10 '19 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 ? – Byron Coetsee Jan 27 '20 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 Jan 27 '20 at 15:29
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)
Alvin George
  • 14,148
  • 92
  • 64
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)
    }
}
Sergio
  • 2,346
  • 2
  • 24
  • 28
epaus
  • 111
  • 4
1

Try finding the search bar by its key:

UITextField *searchField = [self.searchDisplayController.searchBar valueForKey:@"_searchField"];
searchField.font = [[UIFont fontWithName:@"Oswald" size:11];
theprojectabot
  • 1,163
  • 12
  • 19
  • 1
    This might get your app rejected since you are accessing a private property. The Apple docs specifically says this is not allowed. – Widerberg May 19 '14 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;
    }
}
Trong Dinh
  • 363
  • 4
  • 9
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)
        }
    }
}
Skoua
  • 3,373
  • 3
  • 38
  • 51
1

iOS 13 or later:

if #available(iOS 13.0, *) {
    // set your desired font size
    self.searchBar.searchTextField.font = .systemFont(ofSize: 14.0) 
}
Muhammad Yusuf
  • 396
  • 3
  • 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]];
Paul.V
  • 386
  • 1
  • 3
  • 13
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