検索バーのクリアボタン表示制御は通常できません。検索バーにキーワードが入力されていれば、フォーカスが外れていても、クリアボタンが常に表示されている状態になっています。
その動作を変更したい場合、例えば検索バーにフォーカスがあたっている場合のみクリアボタンを表示したい場合、UISearchBarのtextFieldを探してクリアボタンの表示モードを変更する必要があります。
iOS SDKのバージョンによっては、UISearchBar.subviews
を検索すれば見つかる場合もあるようですが、iOS 7/8では、もう一段下の階層にtextFieldが追加されているため、再帰的に検索すると見つけることができます。
ということで、クリアボタンを制御するには、以下のようにUISearchBar
のカテゴリを作成すれば実現することができます。毎回検索バーのクリアボタンを検索するのは面倒なので、最初にアクセスしたときのみ検索しオブジェクトにキャッシュさせておけばいいでしょう。
// UISearchBar+ConfigHacking.h
#import <UIKit/UIKit.h>
@interface UISearchBar (ConfigHacking)
/*!
@abstract UISeachBarのsubviewを再帰的に検索して、TextFieldのclearButtonModeを変更/取得する
@todo UISearchBarの構造が変更された場合、対応する必要がある
*/
@property (nonatomic, readwrite) UITextFieldViewMode textFieldClearButtonMode;
@end
// UISearchBar+ConfigHacking.m
#import "UISearchBar+ConfigHacking.h"
#import <objc/runtime.h>
static const NSUInteger MaxRecursiveDepth = 3;
#pragma mark -
@implementation UISearchBar (ConfigHacking)
- (UITextField *)retrieveTextFieldInView:(UIView *)view depth:(NSUInteger)depth {
if (depth >= MaxRecursiveDepth) {
return nil;
}
for (UIView *subview in view.subviews) {
if ([subview isKindOfClass:[UITextField class]]) {
return (UITextField *)subview;
}
UITextField *textField = [self retrieveTextFieldInView:subview depth:depth+1];
if (textField) {
return textField;
}
}
return nil;
}
- (UITextField *)ch_searchField {
UITextField *textField = objc_getAssociatedObject(self, _cmd);
if (textField) {
return textField;
}
@synchronized(self) {
textField = [self retrieveTextFieldInView:self depth:1];
objc_setAssociatedObject(self, _cmd, textField, OBJC_ASSOCIATION_ASSIGN);
}
return textField;
}
- (UITextFieldViewMode)textFieldClearButtonMode {
UITextField *searchField = [self ch_searchField];
if (searchField) {
return searchField.clearButtonMode;
}
return UITextFieldViewModeAlways;
}
- (void)setTextFieldClearButtonMode:(UITextFieldViewMode)textFieldClearButtonMode {
UITextField *searchField = [self ch_searchField];
if (searchField) {
searchField.clearButtonMode = textFieldClearButtonMode;
}
}
@end
このカテゴリを使えば、検索バーにフォーカスがあたっている時のみクリアボタンを表示したい場合、textFieldClearButtonMode
にUITextFieldViewModeWhilteEditing
を設定すれば変更できます。
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 44)];
self.searchBar.textFieldClearButtonMode = UITextFieldViewModeWhileEditing;
Storyboardに追加した検索バーのクリアボタン表示モードを変更したい場合は、 User defined runtime attributes を使って変更すればよいでしょう。
- Key Path:
textFieldClearButtonMode
- Type:
Number
- Value: 1