如何更改UISearchBar
in 的文本颜色iOS 7
?
在iOS 6
中,我UISearchBar
在自定义 的子视图layoutSubviews
的属性时对 和 进行子类化。UITextField
UISearchBar
但在iOS 7
,UISearchBar
中没有UITextField
它的子视图。如何解决这个问题?
如何更改UISearchBar
in 的文本颜色iOS 7
?
在iOS 6
中,我UISearchBar
在自定义 的子视图layoutSubviews
的属性时对 和 进行子类化。UITextField
UISearchBar
但在iOS 7
,UISearchBar
中没有UITextField
它的子视图。如何解决这个问题?
在 iOS 7 中,要访问 Text Field,您必须在级别上再次重申。像这样更改您的代码
for (UIView *subView in self.searchBar.subviews)
{
for (UIView *secondLevelSubview in subView.subviews){
if ([secondLevelSubview isKindOfClass:[UITextField class]])
{
UITextField *searchBarTextField = (UITextField *)secondLevelSubview;
//set font color here
searchBarTextField.textColor = [UIColor blackColor];
break;
}
}
}
注意:这不是公共 API
或者
您可以使用UIControls 的外观属性,例如
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
注意:外观代理可用于 iOS 9.0+ OutPut
您可以将 设置tintcolor
为应用于 中的关键元素search bar
。
用于tintColor
为前景元素着色。
用于barTintColor
为条形背景着色。
在 iOS v7.0 中,UIView 的所有子类都从基类中派生出它们的 tintColor 行为。有关更多信息,请参阅 UIView 级别的 tintColor 讨论。 苹果文档
您可以通过以下方式设置文本颜色
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor blueColor]];
对于 XCode 6 (iOS8 SDK),以下内容不起作用
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor redColor]];
但以下确实有效(用于部署到 iOS7 和 iOS8)
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
虽然 UIAppearance 协议确实是一个“公共 API”,但 UITextField 并不支持这一点。
如果您查看 UITextField.h 并查找字符串“UI_APPEARANCE_SELECTOR”,您会发现它没有该字符串的实例。如果您查看 UIButton,您会发现很多 - 这些都是 UIAppearance API 官方支持的所有属性。众所周知,UIAppearance API 不支持 UITextField ,因此 Sandeep 答案中的代码并不总是有效,它实际上不是最好的方法。
这是一篇带有有用链接的有用帖子:http ://forums.xamarin.com/discussion/175/uitextfield-appearance
不幸的是,正确的方法很混乱 - 遍历子视图(或 iOS7 的主子视图的子视图)并手动设置。否则你会得到不可靠的结果。但是您可以为 UISearchBar 创建一个类别并添加一个 setTextColor:(UIColor*)color 方法。例子:
- (void)setTextColor:(UIColor*)color
{
for (UIView *v in self.subviews)
{
if([Environment isVersion7OrHigher]) //checks UIDevice#systemVersion
{
for(id subview in v.subviews)
{
if ([subview isKindOfClass:[UITextField class]])
{
((UITextField *)subview).textColor = color;
}
}
}
else
{
if ([v isKindOfClass:[UITextField class]])
{
((UITextField *)v).textColor = color;
}
}
}
}
注意:这应该会导致应用被拒绝!
KVC FTW。这为我做到了。
UITextField *searchField = [self.searchBar valueForKey:@"_searchField"];
searchField.textColor = [UIColor redColor];
您可以像这样设置文本属性
[[UITextField appearanceWhenContainedIn:[<YOUR_CONTROLLER_NAME> class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor], NSFontAttributeName:[UIFont systemFontOfSize:14.0]}];
这是使用 Xamarin 在 C# 中完成的工作示例:
SearchBar = new UISearchBar ();
foreach (var subView in SearchBar.Subviews) {
foreach (var field in subView.Subviews) {
if (field is UITextField) {
UITextField textField = (UITextField)field;
textField.TextColor = UIColor.White;
}
}
}
希望这可以帮助某人。
这似乎是正确的答案https://stackoverflow.com/a/19315895/2493073
它的 Swift 版本是:
UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).textColor = UIColor.blueColor()
这仅适用于 iOS 9.0,为了使其适用于较低版本,您需要遵循此问题。https://stackoverflow.com/a/27807417/2493073
快速扩展
public extension UISearchBar {
public func setTextColor(color: UIColor) {
let svs = subviews.flatMap { $0.subviews }
guard let tf = (svs.filter { $0 is UITextField }).first as? UITextField else { return }
tf.textColor = color
}
}
就我而言,我有多个UISearchBar
对象,它们需要更改textField
字体颜色。appearanceWhenContainedIn
更新一种行为,UISearchBar
但另一种则没有。
我子类化UISearchBar
并实现自定义-(id)initWithFrame:
如下,它可以工作。
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.searchBarStyle = UISearchBarStyleMinimal;
self.tintColor = [UIColor whiteColor];
self.barTintColor = [UIColor whiteColor];
[[UITextField appearanceForTraitCollection:self.traitCollection whenContainedIn:[self class], nil] setDefaultTextAttributes:
@{
NSForegroundColorAttributeName : [UIColor whiteColor]
}];
}
return self;
}
换句话说,appearanceWhenContainedIn: 中的包含语句被视为部分排序。给定一个具体的排序(实际的子视图层次结构),UIKit 在从窗口向下读取实际层次结构时选择作为第一个唯一匹配的部分排序。
所以,appearanceWhenContainedIn:
不会处理所有UISearchBar
的层次结构UIWindow
。它表明了这一点。
使用 appearanceForTraitCollection: 和 appearanceForTraitCollection:whenContainedIn: 方法检索具有指定特征集合的类的代理。
最简单的方法是将此代码放入 viewDidAppear 或 viewWillAppear:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
与其他一些代码不同,这适用于 iOS 8 和 Xcode 6 。它可能会弄乱字体和文本大小等,但您可以在文本属性中更改它。
这会更改应用程序中所有搜索栏的文本颜色。如果您只想更改一个,请使用上面的代码,然后在任何其他带有搜索栏的视图中,使用相同的代码,但将颜色设置为您想要的任何颜色。
您可以在文本字段中使用搜索栏
UISearchBar * searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 50, 320, 44) ];
searchBar.autocorrectionType = UITextAutocapitalizationTypeWords;
searchBar.delegate = self;
searchBar.searchBarStyle = UISearchBarStyleMinimal;
searchBar.barTintColor = [UIColor redColor];
[[UITextField appearanceWhenContainedIn:[searchBar class], nil]setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
[self.view addSubview:searchBar];
Swift 3 中的更新
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.black
尽管我更喜欢使用外观 API,但它不适用于 iOS8。这是我提供的最简单的解决方案:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (self.shouldEnableSearchBar)
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
UITextField *searchBarTextField = [[AFPBaseViewController findSubviewsOfView:self.searchBar ofClass:[UITextField class]] firstObject];
searchBarTextField.textColor = AFPConstantsColorGold;
});
}
}
你甚至可以用这个创建一个 UIView 类别。之所以必须在 viewDidAppear 中调用它,是因为 UISearchBar 实际上包含在一个 ViewController 中,并且在它出现在屏幕上之前不会加载它的所有子视图。它也可以添加到 viewWillAppear 中,但我还没有测试过。
+ (NSArray *)findSubviewsOfView:(UIView *)view ofClass:(Class)class
{
NSMutableArray *targetSubviews = [NSMutableArray new];
for (id subview in view.subviews)
{
if ([subview isKindOfClass:class])
{
[targetSubviews addObject:subview];
}
if ([subview subviews].count)
{
[targetSubviews addObjectsFromArray:[self findSubviewsOfView:subview ofClass:class]];
}
}
return targetSubviews.copy;
}
这是 iOS8 的正确解决方案:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:14], NSForegroundColorAttributeName:[UIColor lightGrayColor]}];
您还必须设置字体,否则字体大小会错误。
本课程将让您完全控制UISearchBar
import UIKit
class SMTSearchBar: UISearchBar {
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
initialize()
}
convenience init() {
self.init(frame: CGRectZero)
initialize()
}
// Style the view
func initialize() {
// Search Area
let searchField = valueForKey("searchField") as! UITextField
searchField.textColor = Colors.White
searchField.font = UIFont(name: Fonts.MuseoSans500, size: 16)
searchField.backgroundColor = Colors.Black.colorWithAlphaComponent(0.1)
// Icons
let searchIcon = UIImage(named: Icons.Search)?.imageWithTint(Colors.White)
let smallClearIconNormal = UIImage(named: Icons.SmallClear)?.imageWithTint(Colors.White)
let smallClearIconHighLight = UIImage(named: Icons.SmallClear)?.imageWithTint(Colors.White.colorWithAlphaComponent(0.5))
setImage(searchIcon, forSearchBarIcon: .Search, state: .Normal)
setImage(smallClearIconHighLight, forSearchBarIcon: .Clear, state: .Highlighted)
setImage(smallClearIconNormal, forSearchBarIcon: .Clear, state: .Normal)
}
func setPlaceHolder(placeholder: String) {
for subView in subviews{
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
textField.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSForegroundColorAttributeName: Colors.White.colorWithAlphaComponent(0.5)])
}
}
}
}
}
用法(在导航栏中)
let searchBar:SMTSearchBar = SMTSearchBar()
searchBar.sizeToFit()
searchBar.setPlaceHolder("Search for cool things")
navigationItem.titleView = searchBar
searchBar.becomeFirstResponder()