Удалить кнопку Очистить (серый x) справа от UISearchBar при нажатии кнопки Отмена
правильно, чтобы начать мой вопрос, вот некоторые экранные проблемы, уже решенные приложением Spotify:
Шаг 1 Spotify: стандартный UISearchBar не в режиме редактирования.
Шаг 1 http://i49.tinypic.com/wbtpwi.png
Шаг 2 Spotify: UISearchBar теперь в режиме редактирования. Введен поисковый запрос. Кнопка "Отмена" скользит справа, и появляется кнопка "Очистить" (серый x).
Шаг 2 http://i45.tinypic.com/161kbvp.png
Шаг 3 Spotify: кнопка отмены нажата; клавиатура выскальзывает, и панель поиска больше не находится в режиме редактирования. Срок поиска остается и серая кнопка x теперь скрыта.
Шаг 3 http://i46.tinypic.com/20utv9v.png
В настоящее время следующий код срабатывает, когда мой кнопка отмены нажата:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
[searchBar setShowsCancelButton:NO animated:YES];
}
какие результаты в:
Шаг 3: панель поиска теперь не в режиме редактирования. Кнопка "Отмена" и клавиатура выскользнули. Поисковый запрос остается, но и серый x.
проблема http://i46.tinypic.com/rlm4w5.png
Итак, мой вопрос таков: учитывая это -resignFirstResponder
(и -endEditing:
, FYI) делает не скрыть серую кнопку x, когда в строке поиска был введен текст, как его скрыть?
еще раз спасибо, друзья.
11 ответов
проблема в том, что UISearchBar не предоставляет текстовое поле и управляет свойствами самого текстового поля. Иногда, значения свойств не то, что вы хотите.
например, в моем собственном приложении я хотел, чтобы стиль клавиатуры для моей панели поиска использовал прозрачный стиль оповещения.
мое решение состояло в том, чтобы пройти через подвиды панели поиска, пока вы не найдете текстовое поле. Затем вы сможете установить clearButtonMode
собственность, используя что-то как UITextFieldViewModeWhileEditing
в качестве параметра.
это должно сделать так, чтобы кнопка clear отображалась только во время редактирования текстового поля.
вы хотите сделать это viewDidLoad
или что-то раннее, поэтому оно установлено до того, как вы начнете его использовать (но после инициализации строки поиска.
for (UIView *subview in searchBar.subviews)
{
if ([subview conformsToProtocol:@protocol(UITextInputTraits)])
{
[(UITextField *)subview setClearButtonMode:UITextFieldViewModeWhileEditing];
}
}
похоже, что iOS 7 изменила иерархию представлений UISearchBar, и текстовое поле находится глубже в представлении (вышеупомянутое решение не сработало для меня). Однако изменение вышеуказанного решения для прохождения всей иерархии работает:
[self configureSearchBarView:[self searchBar]];
- (void)configureSearchBarView:(UIView*)view {
for (UIView *subview in [view subviews]){
[self configureSearchBarView:subview];
}
if ([view conformsToProtocol:@protocol(UITextInputTraits)]) {
[(UITextField *)view setClearButtonMode:UITextFieldViewModeWhileEditing];
}
}
я основываюсь на предыдущих ответах, потому что я начал видеть сбои на iOS 7.1, если я не сделал следующее изменение. Я добавил дополнительный вызов respondsToSelector
для каждого представления, чтобы убедиться в том, что setClearButtonMode:
можно назвать. Я наблюдал пример UISearchBar
получение прошло, что, кажется, соответствует UITextInputTraits
протокол еще не имеет setClearButtonMode:
селектор, поэтому произошел сбой. Пример UISearchBarTextField
также передается и является фактическим объектом для вызова setClearButtonMode:
.
- (void)removeClearButtonFromView:(UIView *)view { if (!view) { return; } for (UIView *subview in view.subviews) { [self removeClearButtonFromView:subview]; } if ([view conformsToProtocol:@protocol(UITextInputTraits)]) { UITextField *textView = (UITextField *)view; if ([textView respondsToSelector:@selector(setClearButtonMode:)]) { [textView setClearButtonMode:UITextFieldViewModeNever]; } } }
лучший способ сделать это в iOS7:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setClearButtonMode:UITextFieldViewModeWhileEditing];
вам нужно получить текстовое поле строки поиска
UITextField *textField = [searchBar valueForKey:@"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;
использовать в - (void)searchBarTextDidBeginEditing: (UISearchBar *)метод searchBar.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
UITextField *textField = [searchBar valueForKey:@"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;
}
чтобы развернуть ответ Jadariens, если вы никогда не хотите, чтобы серый x появился, вам нужно использовать следующее
for (UIView *subview in searchBar.subviews)
{
if ([subview conformsToProtocol:@protocol(UITextInputTraits)])
{
[(UITextField *)subview setClearButtonMode:UITextFieldViewModeNever];
}
}
принятый ответ не работает на iOS7+, вот измененная версия в качестве расширения Swift
extension UIView {
class func removeClearButton(svs: [UIView]) {
for sv in svs {
if let tv = sv as? UITextField where sv.conformsToProtocol(UITextInputTraits) {
tv.clearButtonMode = .Never
return
} else {
UIView.removeClearButton(sv.subviews)
}
}
}
}
использование
UIView.removeClearButton(searchBar.subviews)
ее категория, которую я написал, делает это
категория
@implementation UISearchBar (Additions)
- (void)setClearButtonMode:(UITextFieldViewMode)viewMode {
UITextField *textField = [self findTextFieldInView:self];
[textField setClearButtonMode:viewMode];
}
- (UITextField *)findTextFieldInView:(UIView *)view {
for (UIView *subview in view.subviews) {
if ([subview isKindOfClass:[UITextField class]] ||
[subview.class isSubclassOfClass:[UITextField class]]) {
return (UITextField *)subview;
}
UITextField *textField = [self findTextFieldInView:subview];
if (textField) {
return textField;
}
}
return nil;
}
@end
использование
[searchBar setClearButtonMode:UITextFieldViewModeWhileEditing];
есть лучший способ, чем любой из ответов здесь, и вам не нужно использовать частные API или пересекать подвиды для этого.
UISearchBar имеет встроенный API для этого:
[uisearchbar setImage: forSearchBarIcon: state]
ключ значка панели поиска, который вы хотите, - UISearchBarIconClear, и вы хотите состояние UIControlStateNormal. Затем дайте ему четкое изображение для изображения, и вы закончите.
Итак, это должно выглядеть так это:
[searchBar setImage:clearImage forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];
для значка (x) в строке поиска. Вы можете использовать метод делегата ниже.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = YES;
}
for (UIView *subview in _search_bar.subviews)
{
NSLog(@"%@",subview.subviews);
for (UIView *subview11 in subview.subviews)
{
if ([subview11 conformsToProtocol:@protocol(UITextInputTraits)])
{
[(UITextField *)subview11 setClearButtonMode:UITextFieldViewModeNever];
}
}
}