如何更改 UISearchBar 占位符和图像色调颜色?
Posted
技术标签:
【中文标题】如何更改 UISearchBar 占位符和图像色调颜色?【英文标题】:How to change UISearchBar Placeholder and image tint color? 【发布时间】:2015-06-05 05:00:57 【问题描述】:我已经尝试了几个小时的搜索结果,但我无法弄清楚这一点。也许这是不可能的。我正在尝试更改 UISearchBar 的占位符文本和放大镜的色调。如果这很重要,我只针对 ios 8.0+。这是我的代码以及它现在的样子:
let searchBar = UISearchBar()
searchBar.placeholder = "Search"
searchBar.searchBarStyle = UISearchBarStyle.Minimal
searchBar.tintColor = UIColor.whiteColor()
我希望搜索和放大镜是白色的,或者可能是深绿色。
【问题讨论】:
seachControl.searchBar.placeholder = "" 【参考方案1】:详情
Xcode 版本 11.0 (11A420a),iOS 13,swift 5解决方案
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
完整样本
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)
结果
【讨论】:
当 SearchBar 在 NavigationBar 中但没有成功时,我一直试图让它在 iOS 11 上运行。有什么想法吗? 你好雷纳托。我无法理解你的问题。不能将 SearchBar 添加到 NavigationBar? 非常感谢! 这个解决方案看起来不错,但对于UISearchController
,您需要继承UISearchController
和UISearchBar
。即使那样,清除按钮着色仍然不起作用。任何想法为什么?
很好的解决方案!一个问题是 ClearButtonColor
在 iOS 12.0 中不起作用。【参考方案2】:
如果您有可以使用的自定义图像,则可以使用类似于以下内容的方式设置图像并更改占位符文本颜色:
[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]];
在该示例中,我使用了 PurpleColor,您可以使用 + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha
方法来创建您的自定义深绿色。
编辑:我刚刚意识到你正在用swift写它......呃。快速输入,所以我没有在 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
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)
【讨论】:
这太完美了,非常感谢您。我以前没见过searchBar.valueForKey("searchField") as? UITextField
,这太棒了。您是否也知道如何更改清除按钮(小圆 x)?
我想这将与 setImage 的方式相同,但不是使用 UISearchBarIcon.Search,而是使用 .Clear???我实际上并没有尝试过。除此之外,我知道实际单词“取消”受 searchBar.tintColor...
访问私有属性或 API 肯定会导致您的应用被拒绝。
不要使用私有 API【参考方案3】:
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
【讨论】:
self.searcBar.setTextFieldColor(color: .white) 不起作用,为什么?仍然显示浅浅灰色,但其他颜色正在工作,但白色没有任何想法? ....【参考方案4】:可以在不违反私有api规则的情况下更改文字颜色:
UILabel.appearanceWhenContainedInInstancesOfClasses([UITextField.self]).textColor = UIColor.whiteColor()
【讨论】:
appearanceWhenContainedInInstancesOfClasses 仅适用于 ios9+【参考方案5】:我无法使其与上述任何解决方案一起正常工作。
我创建了以下 UISearchBar 类别,它可以在 iOS 8.4 和 10.3 上正常工作:
UISearchBar+PlaceholderColor.h
#import <UIKit/UIKit.h>
@interface UISearchBar (PlaceholderColor)
- (void)setPlaceholderColor:(UIColor *)placeholderColor;
@end
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
用法:
[mySearchBar setPlaceholderColor:[UIColor redColor]];
重要提示:
确保调用 setPlaceholderColor:AFTER 您的 UISearchBar 已添加到视图并创建了其视图层次结构。
如果您以编程方式打开搜索栏,请将其称为 AFTER 您的 becomeFirstResponder 调用,如下所示:
[mySearchBar becomeFirstResponder];
[searchBar setPlaceholderColor:[UIColor redColor]];
否则,如果您使用 UISearchBarDelegate:
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
[searchBar setPlaceholderColor:[UIColor redColor]];
【讨论】:
【参考方案6】: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
【讨论】:
不错的解决方案!图标工作正常,但占位符文本对我来说并没有改变。【参考方案7】:我做了一个 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])
您可以将其用于您的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))
【讨论】:
【参考方案8】:我找到了一种方法来更改搜索栏中的文本文件。 它适用于 swift 3 和 Xcode8。
首先,继承 UISearchBar 类。
class CustomSearchBar: UISearchBar
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)
你去吧,享受这个。
【讨论】:
你有这个的源代码吗?我无法理解这一点。 嗨@ethanfox27,这是源代码,希望得到帮助。 github.com/JeromeTW/XZY-s-Blog/blob/master/ReadMe.txtgithub.com/JeromeTW/XZY-s-Blog/blob/master/…【参考方案9】:对 Vasily Bodnarchuk 出色答案的小幅更新。
斯威夫特 4+
NSForegroundColorAttributeName
已更改为NSAttributedStringKey.foregroundColor
【讨论】:
【参考方案10】:对于任何试图更改文本但无法看到更新的占位符的人,将其放在此处而不是 viewDidLoad
对我有用。
- (void)viewDidLayoutSubviews
[super viewDidLayoutSubviews];
self.searchBar.placeholder = @"My Custom Text";
【讨论】:
【参考方案11】:刚刚找到这个帖子,对不起,考虑到年龄的问题。然而,它帮助我尝试解决我的问题,并添加到@m_katsifarakis 的答案中,我在他现有的类别中添加了更多内容。
为占位符和输入文本添加额外的颜色和字体支持。
仅在 iOS 13 上进行了测试,因为这就是我所支持的全部。
@interface UISearchBar (ColorandFont)
- (void)setPlaceholderColor:(UIColor *)placeholderColor setPlaceholderFont:(UIFont *)placeholderFont;
- (void)setTextColor:(UIColor *)textColor setTextFont:(UIFont *)textFont;
@end
@implementation UISearchBar (ColorandFont)
//Placeholder Color
- (void)setPlaceholderColor:(UIColor *)placeholderColor setPlaceholderFont:(UIFont *)placeholderFont
UILabel *labelView = [self placeholderText:self];
[labelView setTextColor:placeholderColor];
[labelView setFont:placeholderFont];
- (UILabel *)placeholderText:(UIView *)view
for (UIView *v in [view subviews])
if ([v isKindOfClass:[UILabel class]])
return (UILabel *)v;
UIView *labelView = [self placeholderText:v];
if (labelView)
return (UILabel *)labelView;
return nil;
//Text Color
- (void)setTextColor:(UIColor *)textColor setTextFont:(UIFont *)textFont
UITextField *textView = [self searchBarText:self];
[textView setTextColor:textColor];
[textView setFont:textFont];
- (UITextField *)searchBarText:(UIView *)view
for (UIView *v in [view subviews])
if ([v isKindOfClass:[UITextField class]])
return (UITextField *)v;
UIView *textView = [self searchBarText:v];
if (textView)
return (UITextField *)textView;
return nil;
@end
使用(我在 viewDidLoad 和 Appear 中使用)给定我当前的设置,结果可能会有所不同:
[self.searchBar setPlaceholderColor:[UIColor lightTextColor] setPlaceholderFont:[UIFont italicSystemFontOfSize:13]];
[self.searchBar setTextColor:[UIColor whiteColor] setTextFont:[UIFont systemFontOfSize:16]];
【讨论】:
【参考方案12】:在 Swift 4 中,假设您的搜索控制器设置如下:
let searchController = UISearchController(searchResultsController: nil)
然后设置占位符文本如下:
searchController.searchBar.placeholder = "Here is my custom text"
【讨论】:
问题是如何改变颜色,而不是如何设置文字以上是关于如何更改 UISearchBar 占位符和图像色调颜色?的主要内容,如果未能解决你的问题,请参考以下文章
更改 UISearchBar 内 CLEAR 按钮的 Tint 颜色 NOT CANCEL BUTTON
UISearchBar 不会更改 iOS 12.1 的搜索图标和占位符颜色