ios 如何更改 UISearchBar 占位符和图像色调颜色?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29375696/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change UISearchBar Placeholder and image tint color?
提问by Kyle Bashour
I've been trying search results for hours, but I can't get this figured out. Perhaps it isn't possible. I'm trying to change the tint color of the placeholder text and magnifying glass of a UISearchBar. I'm only targeting iOS 8.0+ if that matters. Here's my code and what it looks like now:
我已经尝试了几个小时的搜索结果,但我无法弄清楚。也许这是不可能的。我正在尝试更改 UISearchBar 的占位符文本和放大镜的色调。如果这很重要,我只针对 iOS 8.0+。这是我的代码以及它现在的样子:
let searchBar = UISearchBar()
searchBar.placeholder = "Search"
searchBar.searchBarStyle = UISearchBarStyle.Minimal
searchBar.tintColor = UIColor.whiteColor()
I'd like for the search and magnifying glass to be white, or perhaps a dark green.
我希望搜索和放大镜是白色的,或者是深绿色的。
回答by Vasily Bodnarchuk
Details
细节
- Xcode Version 11.0 (11A420a), iOS 13, swift 5
- Xcode 版本 11.0 (11A420a),iOS 13,swift 5
Solution
解决方案
import UIKit
extension UISearchBar {
func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField }
func set(textColor: UIColor) { if let textField = getTextField() { textField.textColor = textColor } }
func setPlaceholder(textColor: UIColor) { getTextField()?.setPlaceholder(textColor: textColor) }
func setClearButton(color: UIColor) { getTextField()?.setClearButton(color: color) }
func setTextField(color: UIColor) {
guard let textField = getTextField() else { return }
switch searchBarStyle {
case .minimal:
textField.layer.backgroundColor = color.cgColor
textField.layer.cornerRadius = 6
case .prominent, .default: textField.backgroundColor = color
@unknown default: break
}
}
func setSearchImage(color: UIColor) {
guard let imageView = getTextField()?.leftView as? UIImageView else { return }
imageView.tintColor = color
imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)
}
}
private extension UITextField {
private class Label: UILabel {
private var _textColor = UIColor.lightGray
override var textColor: UIColor! {
set { super.textColor = _textColor }
get { return _textColor }
}
init(label: UILabel, textColor: UIColor = .lightGray) {
_textColor = textColor
super.init(frame: label.frame)
self.text = label.text
self.font = label.font
}
required init?(coder: NSCoder) { super.init(coder: coder) }
}
private class ClearButtonImage {
static private var _image: UIImage?
static private var semaphore = DispatchSemaphore(value: 1)
static func getImage(closure: @escaping (UIImage?)->()) {
DispatchQueue.global(qos: .userInteractive).async {
semaphore.wait()
DispatchQueue.main.async {
if let image = _image { closure(image); semaphore.signal(); return }
guard let window = UIApplication.shared.windows.first else { semaphore.signal(); return }
let searchBar = UISearchBar(frame: CGRect(x: 0, y: -200, width: UIScreen.main.bounds.width, height: 44))
window.rootViewController?.view.addSubview(searchBar)
searchBar.text = "txt"
searchBar.layoutIfNeeded()
_image = searchBar.getTextField()?.getClearButton()?.image(for: .normal)
closure(_image)
searchBar.removeFromSuperview()
semaphore.signal()
}
}
}
}
func setClearButton(color: UIColor) {
ClearButtonImage.getImage { [weak self] image in
guard let image = image,
let button = self?.getClearButton() else { return }
button.imageView?.tintColor = color
button.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal)
}
}
var placeholderLabel: UILabel? { return value(forKey: "placeholderLabel") as? UILabel }
func setPlaceholder(textColor: UIColor) {
guard let placeholderLabel = placeholderLabel else { return }
let label = Label(label: placeholderLabel, textColor: textColor)
setValue(label, forKey: "placeholderLabel")
}
func getClearButton() -> UIButton? { return value(forKey: "clearButton") as? UIButton }
}
Full Sample
完整样本
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: 44))
searchBar.searchBarStyle = .default
view.addSubview(searchBar)
searchBar.placeholder = "placeholder"
searchBar.set(textColor: .brown)
searchBar.setTextField(color: UIColor.green.withAlphaComponent(0.3))
searchBar.setPlaceholder(textColor: .white)
searchBar.setSearchImage(color: .white)
searchBar.setClearButton(color: .red)
}
}
Result
结果
回答by c_rath
If you have a custom image you could use, you can set the image and change the placeholder text color using something similar to the following:
如果您有可以使用的自定义图像,则可以使用类似于以下内容的内容设置图像并更改占位符文本颜色:
[searchBar setImage:[UIImage imageNamed:@"SearchWhite"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
UITextField *searchTextField = [searchBar valueForKey:@"_searchField"];
if ([searchTextField respondsToSelector:@selector(setAttributedPlaceholder:)]) {
UIColor *color = [UIColor purpleColor];
[searchTextField setAttributedPlaceholder:[[NSAttributedString alloc] initWithString:@"Search" attributes:@{NSForegroundColorAttributeName: color}]];
}
In that example I used purpleColor, instead you can use the + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha
method to create your custom dark green color.
在该示例中,我使用了 PurpleColor,而您可以使用该+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha
方法来创建您的自定义深绿色。
EDIT: I just realized you were writing it in swift... duh. Quickly typed this out so I didn't leave the answer in just Obj-C.
编辑:我刚刚意识到你写得很快......呃。快速输入这个,所以我没有只在 Obj-C 中留下答案。
searchBar.setImage(UIImage(named: "SearchWhite"), forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal);
var searchTextField: UITextField? = searchBar.valueForKey("searchField") as? UITextField
if searchTextField!.respondsToSelector(Selector("attributedPlaceholder")) {
var color = UIColor.purpleColor()
let attributeDict = [NSForegroundColorAttributeName: UIColor.purpleColor()]
searchTextField!.attributedPlaceholder = NSAttributedString(string: "search", attributes: attributeDict)
}
Swift 3.0
斯威夫特 3.0
var searchTextField: UITextField? = searchBar.value(forKey: "searchField") as? UITextField
if searchTextField!.responds(to: #selector(getter: UITextField.attributedPlaceholder)) {
let attributeDict = [NSForegroundColorAttributeName: UIColor.white]
searchTextField!.attributedPlaceholder = NSAttributedString(string: "Search", attributes: attributeDict)
}
回答by phitsch
Swift 3: If you want to change the placeholder, clearbutton and magnifier glass
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
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
回答by netshark1000
You can change the color of the text without violating the private api rule:
您可以在不违反私有 api 规则的情况下更改文本的颜色:
UILabel.appearanceWhenContainedInInstancesOfClasses([UITextField.self]).textColor = UIColor.whiteColor()
回答by m_katsifarakis
I could not make it work properly with any of the above solutions.
我无法使用上述任何解决方案使其正常工作。
I created the following UISearchBar category which works properly on iOS 8.4and 10.3:
我创建了以下 UISearchBar 类别,它在iOS 8.4和10.3上正常工作:
UISearchBar+PlaceholderColor.h
UISearchBar+PlaceholderColor.h
#import <UIKit/UIKit.h>
@interface UISearchBar (PlaceholderColor)
- (void)setPlaceholderColor:(UIColor *)placeholderColor;
@end
UISearchBar+PlaceholderColor.m
UISearchBar+PlaceholderColor.m
#import "UISearchBar+PlaceholderColor.h"
@implementation UISearchBar (PlaceholderColor)
- (void)setPlaceholderColor:(UIColor *)placeholderColor {
UILabel *labelView = [self searchBarTextFieldLabelFromView:self];
[labelView setTextColor:placeholderColor];
}
- (UILabel *)searchBarTextFieldLabelFromView:(UIView *)view {
for (UIView *v in [view subviews]) {
if ([v isKindOfClass:[UILabel class]]) {
return (UILabel *)v;
}
UIView *labelView = [self searchBarTextFieldLabelFromView:v];
if (labelView) {
return (UILabel *)labelView;
}
}
return nil;
}
@end
USAGE:
用法:
[mySearchBar setPlaceholderColor:[UIColor redColor]];
IMPORTANT NOTE:
重要的提示:
Make sure that you call setPlaceholderColor: AFTERyour UISearchBar has been added to the view and has created its view hierarchy.
确保在将 UISearchBar 添加到视图并创建其视图层次结构之后调用 setPlaceholderColor: 。
If you open your search bar programmatically, call it AFTERyour becomeFirstResponder call, as such:
如果您以编程方式打开搜索栏,请在 becomeFirstResponder 调用之后调用它,如下所示:
[mySearchBar becomeFirstResponder];
[searchBar setPlaceholderColor:[UIColor redColor]];
Otherwise, if you are leveraging UISearchBarDelegate:
否则,如果您正在利用UISearchBarDelegate:
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setPlaceholderColor:[UIColor redColor]];
}
回答by Abhimanyu Rathore
I made a Swift 4.1 search bar extension:
我做了一个 Swift 4.1 搜索栏扩展:
import Foundation
import UIKit
extension UISearchBar{
func setTextField(placeHolderColor:UIColor = .gray,placeHolder:String = "Search Something",textColor:UIColor = .white,backgroundColor:UIColor = .black,
placeHolderFont:UIFont = UIFont.systemFont(ofSize: 12.0),
textFont:UIFont = UIFont.systemFont(ofSize: 12.0) ){
for item in self.subviews{
for mainView in (item as UIView).subviews{
mainView.backgroundColor = backgroundColor
if mainView is UITextField{
let textField = mainView as? UITextField
if let _textF = textField{
_textF.text = "success"
_textF.textColor = textColor
_textF.font = textFont
_textF.attributedPlaceholder = NSMutableAttributedString.init(string: placeHolder, attributes: [NSAttributedStringKey.foregroundColor : placeHolderColor,
NSAttributedStringKey.font : placeHolderFont])
}
}
}
}
}
}
You can use this for your searchBar
like this :
您可以searchBar
像这样使用它:
controller.searchBar.setTextField(placeHolderColor: .white,
placeHolder: "Search A Pet",
textColor: .white,
backgroundColor: .green,
placeHolderFont: UIFont.systemFont(ofSize: 14.0),
textFont: UIFont.systemFont(ofSize: 14.0))
回答by Geva
extension UISearchBar {
var textField: UITextField? { return value(forKey: "searchField") as? UITextField }
var placeholderLabel: UILabel? { return textField?.value(forKey: "placeholderLabel") as? UILabel }
var icon: UIImageView? { return textField?.leftView as? UIImageView }
var iconColor: UIColor? {
get {
return icon?.tintColor
}
set {
icon?.image = icon?.image?.withRenderingMode(.alwaysTemplate)
icon?.tintColor = newValue
}
}
}
回答by Mike Carpenter
Small update to Vasily Bodnarchuk's great answer.
Vasily Bodnarchuk 的精彩答案的小更新。
Swift 4+
斯威夫特 4+
NSForegroundColorAttributeName
has been changed to NSAttributedStringKey.foregroundColor
NSForegroundColorAttributeName
已更改为 NSAttributedStringKey.foregroundColor
回答by Jerome
I found a way to change the textfiled in search bar. It works in swift 3 and Xcode8.
我找到了一种更改搜索栏中文本文件的方法。它适用于 swift 3 和 Xcode8。
Firstly, subclass the UISearchBar class.
首先,继承 UISearchBar 类。
class CustomSearchBar: UISearchBar {
UISearchBar include a view which has the important textfield you wanted. Following function get the index in subviews.
UISearchBar 包含一个视图,其中包含您想要的重要文本字段。以下函数获取子视图中的索引。
func indexOfSearchFieldInSubviews() -> Int! {
var index: Int!
let searchBarView = subviews[0]
for (i, subview) in searchBarView.subviews.enumerated() {
if subview.isKind(of: UITextField.self) {
index = i
break
}
}
return index
}
override func draw(_ rect: CGRect) {
// Find the index of the search field in the search bar subviews.
if let index = indexOfSearchFieldInSubviews() {
// Access the search field
let searchField: UITextField = subviews[0].subviews[index] as! UITextField
// Set its frame.
searchField.frame = CGRect(x: 5, y: 5, width: frame.size.width - 10, height: frame.size.height - 10)
// Set the font and text color of the search field.
searchField.font = preferredFont
searchField.textColor = preferredTextColor
// Set the placeholder and its color
let attributesDictionary = [NSForegroundColorAttributeName: preferredPlaceholderColor.cgColor]
searchField.attributedPlaceholder = NSAttributedString(string: preferredPlaceholder, attributes: attributesDictionary)
// Set the background color of the search field.
searchField.backgroundColor = barTintColor
}
super.draw(rect)
}
There you go, enjoy for this.
你去吧,享受这个。
回答by skensell
For anybody just trying to change the text and having trouble seeing the updated placeholder, it worked for me by putting it here instead of viewDidLoad
.
对于任何试图更改文本并且无法看到更新的占位符的人来说,将它放在这里而不是viewDidLoad
.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.searchBar.placeholder = @"My Custom Text";
}