Удалить кнопку очистки (серый x) справа от UISearchBar, когда кнопка отмены нажата
Хорошо, для начала мой вопрос, вот несколько скриншотов проблемы, уже решенной приложением Spotify:
Шаг 1: Стандартный UISearchBar не находится в режиме редактирования.
Шаг Spotify 2: UISearchBar теперь в режиме редактирования. Введено условие поиска. Кнопка Отмена скользит справа, и появляется кнопка очистки (серый х).
Шаг 3: кнопка отмены нажата; клавиатура выдвигается, и панель поиска больше не находится в режиме редактирования. Поисковый термин остается, а серая кнопка x теперь скрыта.
В настоящее время следующий код срабатывает при нажатии моей кнопки отмены:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
[searchBar setShowsCancelButton:NO animated:YES];
}
Что приводит к:
Мой шаг 3: панель поиска теперь не в режиме редактирования. Кнопка отмены и клавиатура выдвинулись. Поисковый термин остается, но серый х.
Итак, мой вопрос таков: учитывая, что -resignFirstResponder
(и -endEditing:
, FYI) не скрывает серую кнопку x, когда в строку поиска введен текст, как ее скрыть?
Еще раз спасибо, друзья.
Ответы
Ответ 1
Проблема заключается в том, что UISearchBar не предоставляет текстовое поле и управляет свойствами самого текстового поля. Иногда значения свойств не то, что вы хотите.
Например, в моем собственном приложении я хотел, чтобы стиль клавиатуры для моей панели поиска использовал прозрачный стиль оповещения.
Мое решение состояло в том, чтобы пройти через подзоны панели поиска, пока не найдете текстовое поле. Затем вы должны установить свойство clearButtonMode
, используя в качестве параметра что-то вроде UITextFieldViewModeWhileEditing
.
Это должно сделать так, чтобы кнопка очистки отображалась только во время редактирования текстового поля.
Вы хотите сделать это на viewDidLoad
или что-то рано, поэтому установите его перед тем, как начать использовать его (но после инициализации строки поиска.
for (UIView *subview in searchBar.subviews)
{
if ([subview conformsToProtocol:@protocol(UITextInputTraits)])
{
[(UITextField *)subview setClearButtonMode:UITextFieldViewModeWhileEditing];
}
}
Ответ 2
Похоже, что 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];
}
}
Ответ 3
Я основываюсь на предыдущих ответах, потому что я начал видеть сбои на 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];
}
}
}
Ответ 4
Лучший способ сделать это в iOS7:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setClearButtonMode:UITextFieldViewModeWhileEditing];
Ответ 5
Вам нужно получить textField строки поиска
UITextField *textField = [searchBar valueForKey:@"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;
использовать in - (void) searchBarTextDidBeginEditing: (UISearchBar *) метод поискаBar.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
UITextField *textField = [searchBar valueForKey:@"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;
}
Ответ 6
Чтобы развернуть на Jadariens ответ, если вы никогда не хотите, чтобы серый x появился, вам нужно использовать следующие
for (UIView *subview in searchBar.subviews)
{
if ([subview conformsToProtocol:@protocol(UITextInputTraits)])
{
[(UITextField *)subview setClearButtonMode:UITextFieldViewModeNever];
}
}
Ответ 7
Принятый ответ не работает на 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)
Ответ 8
Hers - это категория, которую я написал, которая делает это
Категория
@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];
Ответ 9
Здесь лучше, чем любой из ответов, и вам не нужно использовать частные API или перехватывать подзаголовки, чтобы это сделать.
UISearchBar имеет встроенный API для этого:
[UISearchBar setImage: forSearchBarIcon: состояние]
Значок значка SearchBar, который вы хотите, - UISearchBarIconClear, и вы хотите состояние UIControlStateNormal. Затем дайте ему четкое изображение для изображения, и все готово.
Итак, это должно выглядеть так:
[searchBar setImage:clearImage forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];
Ответ 10
Для значка (x) в searchBar. Вы можете использовать ниже метод делегата.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = YES;
}
Ответ 11
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];
}
}
}