Change the font size of UISearchBar

2019-01-10 11:26发布

问题:

How can I change the font size of UISearchBar ?

Edit:
Answer

for(int i =0; i<[searchbar.subviews count]; i++) {
        if([[searchbar.subviews objectAtIndex:i] isKindOfClass:[UITextField class]])
            [(UITextField*)[searchbar.subviews objectAtIndex:i] setFont:[UIFont fontWithName:@"Helvetica" size:12]];
    }

Thanks
Pankaj

回答1:

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.



回答2:

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.



回答3:

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)



回答4:

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]];


回答5:

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;


回答6:

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)



回答7:

In swift 3 , you can achieve this by :

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = UIFont(name: "AvenirNextCondensed-Regular", size: 17.0)


回答8:

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];
  }
}


回答9:

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)


回答10:

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"
}


回答11:

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)
    }
}


回答12:

Try finding the search bar by its key:

UITextField *searchField = [self.searchDisplayController.searchBar valueForKey:@"_searchField"];
searchField.font = [[UIFont fontWithName:@"Oswald" size:11];


回答13:

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;
    }
}


回答14:

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]];