Подтвердить что ты не робот

Удалить кнопку очистки (серый x) справа от UISearchBar, когда кнопка отмены нажата

Хорошо, для начала мой вопрос, вот несколько скриншотов проблемы, уже решенной приложением Spotify:

Шаг 1: Стандартный UISearchBar не находится в режиме редактирования.

Step 1

Шаг Spotify 2: UISearchBar теперь в режиме редактирования. Введено условие поиска. Кнопка Отмена скользит справа, и появляется кнопка очистки (серый х).

Step 2

Шаг 3: кнопка отмены нажата; клавиатура выдвигается, и панель поиска больше не находится в режиме редактирования. Поисковый термин остается, а серая кнопка x теперь скрыта.

Step 3

В настоящее время следующий код срабатывает при нажатии моей кнопки отмены:

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [searchBar resignFirstResponder];
    [searchBar setShowsCancelButton:NO animated:YES];
}

Что приводит к:

Мой шаг 3: панель поиска теперь не в режиме редактирования. Кнопка отмены и клавиатура выдвинулись. Поисковый термин остается, но серый х.

Problem

Итак, мой вопрос таков: учитывая, что -resignFirstResponder-endEditing:, FYI) не скрывает серую кнопку x, когда в строку поиска введен текст, как ее скрыть?

Еще раз спасибо, друзья.

4b9b3361

Ответ 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];
        }
    }

}