Ios7 iOS 7中的UISearchBar文本颜色更改

Ios7 iOS 7中的UISearchBar文本颜色更改,ios7,uisearchbar,Ios7,Uisearchbar,如何在iOS 7中更改UISearchBar的文本颜色 在ios6中,我对UISearchBar进行了子类化,并在layoutSubviews中自定义UITextField的子视图的属性 但是在ios7中,UISearchBar没有UITextField作为其子视图。如何解决此问题?在iOS 7中,要访问文本字段,您必须在更高级别上重复。像这样更改代码 for (UIView *subView in self.searchBar.subviews) { for (UIView *seco

如何在
iOS 7
中更改
UISearchBar
的文本颜色

ios6
中,我对
UISearchBar
进行了子类化,并在
layoutSubviews
中自定义
UITextField
的子视图的属性


但是在
ios7
中,
UISearchBar
没有
UITextField
作为其子视图。如何解决此问题?

在iOS 7中,要访问文本字段,您必须在更高级别上重复。像这样更改代码

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

您可以使用uicontrol的外观属性,如

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
注意:外观代理可用于iOS 9.0+ 输出

您可以将
tintcolor
设置为应用于
搜索栏中的关键元素

使用
tintColor
为前景元素着色

使用
barTintColor
为条形图背景着色

在iOS v7.0中,UIView的所有子类都从基类派生其tintColor行为。有关更多信息,请参阅UIView级别的tintColor讨论。

您可以通过以下方式设置文本颜色

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor blueColor]];

虽然UIAppearance协议确实是一个“公共API”,但UITextField并不支持这一点

如果查看UITextField.h并查找字符串“UI\u外观\u选择器”,您将看到它没有此字符串的实例。如果您查看UIButton,您会发现很多—这些都是UIAppearance API正式支持的属性。众所周知,UIExtField不受UIAppearance API支持,因此Sandeep答案中的代码并不总是有效的,实际上这不是最好的方法

这是一篇有用的文章,包含有用的链接:

不幸的是,正确的方法很混乱——迭代子视图(或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]}];
[[UITextField appearancewhen containedin:[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;
        }
    }
}

希望这对其他人有所帮助。

尽管我更喜欢使用外观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类别。在ViewDidDisplay中必须调用它的原因是UISearchBar实际上包含在ViewController中,并且在它出现在屏幕上之前不会加载它的所有子视图。它可以添加到视图中,但我还没有测试它

+ (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;
}
对于XCode 6(iOS8 SDK),以下内容不起作用

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor redColor]];
但以下方法确实有效(用于部署到iOS7和iOS8)


最简单的方法是将此代码放入ViewDidDisplay或ViewWillDisplay中:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
这适用于iOS 8和Xcode 6,与其他一些代码不同。它可能会弄乱字体和文本大小等,但您可以在文本属性中更改它们


这将更改应用程序中所有搜索栏的文本颜色。如果您只想更改一个,请使用上述代码,然后在任何其他带有搜索栏的视图中,使用相同的代码,但将颜色设置为您想要的颜色。

这是iOS8的正确解决方案:

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

您还必须设置字体,否则,字体大小将出错。

在我的例子中,我有多个
UISearchBar
对象,它们需要更改
textField
字体颜色。包含在
更新一个
ui搜索栏
行为中的
会出现,但另一个不会

我将
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;
}
说,

换句话说,在 包含时的外观:被视为偏序。给予 具体排序(实际子视图层次),UIKit选择 读取时第一个唯一匹配的偏序 从窗口向下的实际层次结构

因此,
appearancewhen contained:
不会处理
ui窗口
层次结构中的所有
ui搜索栏
。这表明

使用appearanceForTraitCollection:和 appearanceForTraitCollection:当包含在中时:检索 具有指定特征集合的类的代理


您可以在文本字段内使用搜索栏

 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版本是:

UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).textColor = UIColor.blueColor()

这只适用于iOS 9.0,为了使其适用于较低版本,您需要遵循此问题

快速扩展

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


用法(在导航栏中)


在Swift 3中更新

UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.black

现在,在得到我的文本字段后,如果我设置了文本字段的右视图,它不会显示它,你能建议我怎么做吗?我认为这不是iOS的正确答案。请看下面的答案:@spotdog13:正如您所建议的,这将为应用程序中的所有搜索栏设置外观,而不是特定的搜索栏。我认为,如果您对同一应用程序中的搜索栏设置不同的主题,你没有遵循一个好的UI设计…整个应用程序中重复使用的同一个小部件应该看起来相同,以避免用户产生混淆,这正是外观代理的目的。否决票是因为它很脆弱,并且是一个可供选择的公共API
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()
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.black