改变UISearchBar的字体大小。

51

如何更改UISearchBar的字体大小?


请查看此问题:https://dev59.com/amIk5IYBdhLWcg3wke3M - Axel Guilmin
19个回答

162

我建议iOS 5.0及以上版本采取另一种不同的选项:

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

iOS 8的适用版本(由Mike Gledhill提供的链接):

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

iOS 9及以上版本:

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

这样你就不需要为应用中的每个搜索栏枚举子视图而烦恼了。


5
这是使用苹果API的正确答案!忽略这里推荐的任何其他内容。 - Yariv Nissim
7
这不起作用。要让外观代理在特定的类/方法中起作用,该类头文件需要针对该方法具有UI_APPEARANCE_SELECTOR。如果您打开UITextField,您会注意到它没有任何UI_APPEARANCE_SELECTOR注释。 - Bart Vandendriessche
3
当我在程序中动态添加UISearchBar并将其添加到表格视图之后,将这行代码放在声明之后就可以起作用。如果放在之前,则不起作用。如果您是通过Interface Builder添加搜索功能,我不确定它会如何工作。 - Nick
1
这似乎不适用于iOS 7+。我认为这是因为缺少代理方法 :-) - Tatarasanu Victor
1
对于iOS 11及以上版本,只需设置UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [...]即可。 - Evils
显示剩余7条评论

19

执行此操作的安全方式如下:

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

为什么这种方法比被接受的答案更安全呢?因为它不依赖于UITextField索引保持不变。(同时也是一个更干净的循环)


这段代码在未来的更新中唯一可能出现问题的方式是搜索栏不再作为UITextField的子视图。但即使如此,它也不会崩溃。 - Nicolas Miari
4
在iOS 8中无法正常工作,因为视图层次结构已更改。文本字段不再位于顶级。由于您的搜索不是递归的,所以它找不到文本字段。 - Pwner

16

被接受的答案不是推荐的在UISearchBar上应用字体的方法。最好避免此方法,并使用@rafalkitta或@josema提供的答案。

但要小心,这将应用于整个应用程序中的所有搜索栏。为了将此方法应用于特定的搜索栏:创建UISearchBar的一个子类,并像下面这样设置UITextFielddefaultTextAttributes

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;

最佳答案,谢谢。 - Mona

15
UISearchBar包含一个UITextField,但是没有属性可以访问它。因此,没有标准的方法来实现它。
但是有一种非标准的方法来解决这个问题。 UISearchBar继承自UIView,您可以使用[searchBar subviews]访问它的子视图。 如果在控制台中打印出它的子视图,你会看到它有这些视图。
UISearchBarBackground, UISearchBarTextField.
因此,要更改字体大小,您只需要这样做
    UITextField *textField = [[searchBar subviews] objectAtIndex:1];
[textField setFont:[UIFont fontWithName:@"Helvetica" size:40]];

但是,如果UISearchBar在将来发生更改,并且textfield不再位于位置1,则您的程序将崩溃,因此最好通过子视图检查UITextField的位置,然后设置字体大小。


谢谢,它完美地运行了...我稍微编辑了你的代码,并在这里发布了它作为编辑。 - pankaj
8
因为它不是安全和推荐的方法,所以被投票降低了。更好的选择是使用@josema.vitaminew的答案。 - skornos

12
您可以使用 KVC(键值编码)来获取文本字段。
UITextField *textField = [self.searchBar valueForKey: @"_searchField"];
[textField setTextColor:[UIColor redColor]];
[textField setFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:17.0]];

1
这对未来来说是有风险的。 - Hassy
1
这确实是冒一定的风险,但是它已经运行了几年了。有些应用程序甚至没有活过那么久。如果您使用此解决方案,请确保在发布新iOS版本之前进行测试。 - Adriano Spadoni
嘿@刘俊利,我稍后会检查一下,也许这个解决方案已经不再有效了,它预计会停止工作,自从我发布它以来已经有将近5年了。 - Adriano Spadoni
@AdrianoSpadoni 我明白了。它在 iOS 7 ~ iOS 12 上运行得非常好。谢谢! - 刘俊利

12

在 Swift 2.0 中,对于以编程方式创建的搜索栏,您可以执行以下操作:

override func layoutSubviews() {
  super.layoutSubviews()

  let textFieldInsideSearchBar = self.searchBar.valueForKey("searchField") as! UITextField
  textFieldInsideSearchBar.font = UIFont.systemFontOfSize(20)
 }
在这种情况下,我将代码放在UIView子类中,但它也可以在其他地方使用(例如从UIViewController的viewWillAppear方法中)

在这个案例中,我把代码放在一个UIView子类中,但它也可以在其他地方使用(比如在UIViewController的viewWillAppear方法中)


9
在 Swift 3 中,您可以通过以下方式实现此操作:
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).font = UIFont(name: "AvenirNextCondensed-Regular", size: 17.0)

它对我有用。只是当尝试.font时,代码自动补全功能无法正常工作。 - Peter Parker

6

您不应该像其他答案中那样使用私有API。如果您想要在整个应用程序中自定义搜索栏,可以使用类的外观代理。它允许修改搜索栏文本属性、占位符属性、取消按钮、文本字段背景图像、背景图像等。 使用示例:

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
当提供了defaultTextAttributes时,就不需要使用attributedPlaceholder - Miroslav Hrivik

5

UITextField的外观设置无法应用于以编程方式创建的UISearchBar。您需要使用递归解决方法。

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

一般来说,这是最好的解决方案。只要内部文本字段确实是 UITextField(或其子类)并且在子视图层次结构中的某个位置,它就不受版本影响。我不明白为什么你要使用 UIAppearance。为什么不直接设置属性呢? - Dima
@Dima 我正在使用 UIAppearance,因为我首先通过外观代理设置了字体和文本颜色值,但是当您以编程方式创建搜索栏时,系统不会选择它,这就是为什么我正在使用此解决方法+来自外观的值,以便如果我决定在将来更改这些值,它们将在整个应用程序中得到更改。 - Eugene

4

iOS 13+

  searchBar.searchTextField.font = UIFont(name: "YOUR-FONT-NAME", size: 13)

1
请考虑在您的代码中提供一些上下文。建议简要解释您的答案如何/为什么有效。 - ZGski
2
嗯..上下文:这个问题。它是如何工作的:你需要问苹果公司。还有什么需要帮助的,@ZGski? - Byron Coetsee
这个工作原理的简要说明可能包括:UISearchBar 的视图层次结构(或者至少是我们关心的视图)。 - ZGski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接