iOS 7
のUISearchBar
のテキストの色を変更するには?
iOS 6
では、UISearchBar
をサブクラス化し、layoutSubviews
ではUITextField
のUISearchBar
サブビューのプロパティをカスタマイズしていました。
ただし、iOS 7
では、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ではありません
[〜#〜] or [〜#〜]
使用できますappearanceUIControlsのプロパティ、
[[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の説明を参照してください。 Apple Doc
テキストの色を設定するには
[[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によって公式にサポートされているすべてのプロパティです。 UITextFieldがUIAppearance APIでサポートされていないことはよく知られているため、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]}];
これは正しい答えのようです https://stackoverflow.com/a/19315895/249307
Swiftバージョンは:
UITextField.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).textColor = UIColor.blueColor()
これはiOS 9.0でのみ動作します。下位バージョンで動作させるには、この質問に従う必要があります。 https://stackoverflow.com/a/27807417/249307
Swift Extension
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
}
}
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;
}
}
}
これが誰かを助けることを願っています。
私の場合、複数のUISearchBar
オブジェクトがあり、textField
フォントの色を変更する必要があります。 appearanceWhenContainedIn
は1つの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;
}
IAppearance Protocol Reference は、
つまり、appearanceWhenContainedIn:の包含ステートメントは、部分的な順序付けとして扱われます。具体的な順序(実際のサブビュー階層)が与えられると、UIKitは、ウィンドウから下の実際の階層を読み取るときに最初の一意の一致である部分順序を選択します。
そう、 appearanceWhenContainedIn:
は、UISearchBar
の階層のすべてのUIWindow
を処理しません。そして、それはそれを示唆しています。
AspectForForTraitCollection:およびappearanceForTraitCollection:whenContainedIn:メソッドを使用して、指定された特性コレクションを持つクラスのプロキシを取得します。
テキストフィールド内で検索バーを使用できます
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.appearance(whenContainedInInstancesOf: [UISearchBar.self]).textColor = UIColor.black
最も簡単な方法は、次のコードを入力することですviewDidAppearまたはviewWillAppear:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
これはiOS 8およびXcode 6で動作します、他のコードの一部とは異なります。フォントやテキストサイズなどを変更できますが、テキスト属性で変更できます。
これにより、アプリのall検索バーのテキストの色が変わります。 1つだけを変更する場合は、上記のコードを使用してから、検索バーを備えた他のビューで同じコードを使用しますが、色は任意に設定します。
このクラスにより、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()
外観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]}];
フォントも設定する必要があります。そうしないと、フォントサイズが間違ってしまいます。