UISearchBar 更改占位符颜色

52
有没有人有想法或者代码示例,可以让我改变UISearchBar占位文本的文本颜色?

我认为这篇文章会对你有所帮助 https://dev59.com/Q3M_5IYBdhLWcg3whzrx - frankWhite
我已经看过了。这篇文章涉及到UITextfield。子类化UITextfield并覆盖-drawPlaceholderInRect方法肯定会有所帮助。然而,UISearchBar不是UITextfield的子类,因此我无法覆盖此方法。 - csotiriou
抱歉,我不知道这个。UISearchBar是UIView的子类,我认为您可以从中创建子类并尝试覆盖drawRect方法,在其中添加来自先前帖子的代码。也许这会有所帮助。 - frankWhite
针对Swift 3,我在这里找到了一个解决方案:轻松自定义文本框 - Jerome
18个回答

82

对于 iOS5+ 使用外观代理

[[UILabel appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor redColor]];

自从我发帖以来,我已经找到了答案,而且这确实是最好的方法。干净、简单,而且不会破坏任何东西。 - csotiriou
10
这并不是有效的做法。UILabel不支持这种自定义,因为UILabel的"textColor"属性没有像文档要求的那样标记为"UI_APPEARANCE_SELECTOR"。请参见https://dev59.com/_mgt5IYBdhLWcg3wwwG-。 - Joshua J. McKinnon
只有在Storyboard中添加一些占位符,这段代码才能正常工作。如果我们的Storyboard中没有占位符,直接通过代码设置占位符是行不通的。很奇怪。 - sach
7
我无意中给了这个东西点赞。它不好用。人们应该使用:https://dev59.com/Q3M_5IYBdhLWcg3whzrx - Katedral Pillon
这不是有效的答案,请看下面的答案 - Boris Nikolic

31

Change UITextField's placeholder text color programmatically中找到答案。

// Get the instance of the UITextField of the search bar
UITextField *searchField = [searchBar valueForKey:@"_searchField"];

// Change search bar text color
searchField.textColor = [UIColor redColor];

// Change the search bar placeholder text color
[searchField setValue:[UIColor blueColor] forKeyPath:@"_placeholderLabel.textColor"];

有人尝试使用那段代码提交应用程序吗?理论上不应该有太大问题...但是谁能百分之百确定呢... - jimpic
2
虽然这段代码可以运行,但是我不会相信任何提交该应用程序的人,因为它违反了苹果的规定。 - csotiriou
我的应用程序使用这个解决方案可以提交到App Store。 :) - Senry
8
我担心随着iOS更新,这个应用可能会突然崩溃。 - jpswain
prompt 参数怎么样? - fatuhoku

21

第一种解决方案是可以的,但如果您使用多个UISearchBar或创建大量实例,则可能会失败。对我来说始终有效的解决方案是直接在UITextField上使用外观代理。

   NSDictionary *placeholderAttributes = @{
                                            NSForegroundColorAttributeName: [UIColor darkButtonColor],
                                            NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:15],
                                            };

    NSAttributedString *attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.searchBar.placeholder
                                                                                attributes:placeholderAttributes];

    [[UITextField appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setAttributedPlaceholder:attributedPlaceholder];

1
这是唯一一个对我有效的解决方案,其他的解决方案在来回导航视图控制器层次结构并销毁/重新创建搜索栏时都失败了。 - DTs
这应该是ObjC/iOS 13的被接受的解决方案。 - Peter Suwara

18

这里是Swift的解决方案:

Swift 2

var textFieldInsideSearchBar = searchBar.valueForKey("searchField") as? UITextField
textFieldInsideSearchBar?.textColor = UIColor.whiteColor()

var textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.valueForKey("placeholderLabel") as? UILabel
textFieldInsideSearchBarLabel?.textColor = UIColor.whiteColor()

Swift 3

let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField
textFieldInsideSearchBar?.textColor = UIColor.white

let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel
textFieldInsideSearchBarLabel?.textColor = UIColor.white

我也这么认为。这是其他用户推荐的相同解决方案。 - derdida
prompt怎么样?!(不是占位符) - fatuhoku
尝试为textFieldInsideSearchBar设置tintcolor - 应该可以正常工作! - derdida
2
适用于iOS 10.2.1。 - norbDEV
工作得很好,但你能在这个主题中链接到苹果文档吗?我找不到它。提前致谢。 - Jeff

13

iOS 13.0及以上版本很容易实现,您只需使用搜索栏的searchTextField属性即可更新占位符的属性。

self.searchController.searchBar.searchTextField.attributedPlaceholder =  NSAttributedString.init(string: "Search anything...", attributes: [NSAttributedString.Key.foregroundColor:UIColor.red])

一行解决方案


11

试试这个,看看效果:(我用 Swift 4.1 和 Xcode 9.3-beta4 测试了以下代码)

@IBOutlet weak var sbSearchBar: UISearchBar!

if let textfield = sbSearchBar.value(forKey: "searchField") as? UITextField {

    textfield.backgroundColor = UIColor.yellow
    textfield.attributedPlaceholder = NSAttributedString(string: textfield.placeholder ?? "", attributes: [NSAttributedStringKey.foregroundColor : UIColor.red])

    textfield.textColor = UIColor.green

    if let leftView = textfield.leftView as? UIImageView {
        leftView.image = leftView.image?.withRenderingMode(.alwaysTemplate)
        leftView.tintColor = UIColor.red
    }
}

这是结果:

在此输入图片描述


1
太棒了,但如果没有记录,你认为它作为接口有多可靠?如果它不会导致应用程序被拒绝并且苹果不太可能突然更改它,我会使用它。(不知道他们为什么要这样做) - clearlight

7
if let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as ? UITextField {
    textFieldInsideSearchBar ? .textColor = UIColor.white

    if let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as ? UILabel {
        textFieldInsideSearchBarLabel ? .textColor = UIColor.white

        if let clearButton = textFieldInsideSearchBar ? .value(forKey: "clearButton") as!UIButton {

            clearButton.setImage(clearButton.imageView ? .image ? .withRenderingMode(.alwaysTemplate),
                for : .normal)
            clearButton.tintColor = UIColor.white
        }
    }

    let glassIconView = textFieldInsideSearchBar ? .leftView as ? UIImageView

    glassIconView ? .image = glassIconView ? .image ? .withRenderingMode(.alwaysTemplate)
    glassIconView ? .tintColor = UIColor.white
}

6

Swift 5 - iOS 13:

对于卡住的人,我告诉你们,这只能在viewDidLayoutSubviews中工作,而不能在viewDidLoad中。

override func viewDidLayoutSubviews() {

    setupSearchBar(searchBar: YourSearchBar)

}

    func setupSearchBar(searchBar : UISearchBar) {

    searchBar.setPlaceholderTextColorTo(color: UIColor.white)        

   }

extension UISearchBar
{
    func setPlaceholderTextColorTo(color: UIColor)
    {
        let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField
        textFieldInsideSearchBar?.textColor = color
        let textFieldInsideSearchBarLabel = textFieldInsideSearchBar!.value(forKey: "placeholderLabel") as? UILabel
        textFieldInsideSearchBarLabel?.textColor = color
    }
}

愉快地编码 :)


4

IOS 13上对我有用。

searchBar.searchTextField.attributedPlaceholder = NSAttributedString(
    string: "Search something blabla",
    attributes: [.foregroundColor: UIColor.red]
)

这里有最佳答案 - undefined

4

看起来苹果不想让我们在UISearchBar类中玩弄占位符颜色。那么,让我们创建自己的占位符标签!

  • 无需子类化。
  • 适用于iOS 13 SDK。
  • 只需一个无害的解决方法。

enter image description here

let searchBar = searchController.searchBar
// ...
// Configure `searchBar` if needed
// ...

let searchTextField: UITextField
if #available(iOS 13, *) {
    searchTextField = searchBar.searchTextField
} else {
    searchTextField = (searchBar.value(forKey: "searchField") as? UITextField) ?? UITextField()
}

// Since iOS 13 SDK, there is no accessor to get the placeholder label.
// This is the only workaround that might cause issued during the review.
if let systemPlaceholderLabel = searchTextField.value(forKey: "placeholderLabel") as? UILabel {
    // Empty or `nil` strings cause placeholder label to be hidden by the search bar
    searchBar.placeholder = " "

    // Create our own placeholder label
    let placeholderLabel = UILabel(frame: .zero)

    placeholderLabel.text = "Search"
    placeholderLabel.font = UIFont.systemFont(ofSize: 17.0, weight: .regular)
    placeholderLabel.textColor = UIColor.blue.withAlphaComponent(0.5)

    systemPlaceholderLabel.addSubview(placeholderLabel)

    // Layout label to be a "new" placeholder
    placeholderLabel.leadingAnchor.constraint(equalTo: systemPlaceholderLabel.leadingAnchor).isActive = true
    placeholderLabel.topAnchor.constraint(equalTo: systemPlaceholderLabel.topAnchor).isActive = true
    placeholderLabel.bottomAnchor.constraint(equalTo: systemPlaceholderLabel.bottomAnchor).isActive = true
    placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
    placeholderLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
} else {
    searchBar.placeholder = ""
}

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