Могу ли я подключиться к кнопке очистки UISearchBar? - PullRequest
36 голосов
/ 29 мая 2009

В моем интерфейсе есть UISearchBar, и я хочу настроить поведение маленькой кнопки очистки, которая появляется в строке поиска после ввода некоторого текста (появляется маленький серый кружок с крестиком в нем, появляется на правой стороне поля поиска).

По сути, я хочу, чтобы он не только очищал текст панели поиска (которая является реализацией по умолчанию), но также очищал некоторые другие вещи из моего интерфейса, но вызывал один из моих собственных методов.

Я не могу найти ничего в документах для класса UISearchBar или протокола UISearchBarDelegate - похоже, вы не можете напрямую получить доступ к этому поведению.

Единственное, что я заметил, было то, что в документах объяснялось, что метод делегата:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;

вызывается после нажатия кнопки очистки.

Вначале я написал некоторый код в этом методе, который проверял свойство text строки поиска, и если он был пустым, то он очищался и делал все остальные мои вещи.

Две проблемы, которые это, хотя:

Во-первых, по какой-то причине я не могу понять, даже если я говорю поисковой строке resignFirstResponder в конце моего метода, что-то где-то устанавливает его обратно в становлениеFirstResponder. Действительно раздражает ...

Во-вторых, если пользователь не использует кнопку очистки и просто удаляет текст на панели с помощью кнопки удаления на клавиатуре, этот метод отключается, и результаты его поиска исчезают. Не хорошо.

Любой совет или указатели в правильном направлении были бы великолепны!

Спасибо!

Ответы [ 9 ]

17 голосов
/ 09 апреля 2014

Нашли лучшее решение для этой проблемы:)

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
    if ([searchText length] == 0) {
        [self performSelector:@selector(hideKeyboardWithSearchBar:) withObject:searchBar afterDelay:0];
    }
}

- (void)hideKeyboardWithSearchBar:(UISearchBar *)searchBar{   
    [searchBar resignFirstResponder];   
}
11 голосов
/ 04 октября 2010

Ответ, который был принят, неверен. Это можно сделать, я просто понял это и разместил в другом вопросе:

UISearchbar clearButton заставляет клавиатуру появиться

Лучший

7 голосов
/ 25 ноября 2015

Swift версия обрабатывает закрытие клавиатуры при нажатии кнопки очистки:

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
    if searchText.characters.count == 0 {
        performSelector("hideKeyboardWithSearchBar:", withObject:searchBar, afterDelay:0)
    }
}

func hideKeyboardWithSearchBar(bar:UISearchBar) {
    bar.resignFirstResponder()
}
7 голосов
/ 10 февраля 2010

У меня есть этот код в моем приложении. Разница в том, что я не поддерживаю «живой поиск», а вместо этого начинаю поиск, когда пользователь касается кнопки поиска на клавиатуре:

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    if ([searchBar.text isEqualToString:@""]) {
        //Clear stuff here
    }
}
1 голос
/ 23 мая 2014

Вы можете попробовать это:

- (void)viewDidLoad
{
    [super viewDidLoad];
    for (UIView *view in searchBar.subviews){
        for (UITextField *tf in view.subviews) {
            if ([tf isKindOfClass: [UITextField class]]) {
                tf.delegate = self;
                break;
            }
        }
    }
}

- (BOOL)textFieldShouldClear:(UITextField *)textField {
     // your code
    return YES;
}
1 голос
/ 14 декабря 2013

Так как это приходит первым, и, насколько я понимаю, вопрос не был должным образом решен, я решил опубликовать свое решение.

1) Вам нужно получить ссылку на textField внутри панели поиска 2) Вам нужно поймать, что textField очищается при его запуске.

Это довольно просто. Вот один из способов.

a) Убедитесь, что вы сделали свой класс a, так как вы будете использовать метод делегата textField внутри searchBar. б) Кроме того, подключите панель поиска к розетке в вашем классе. Я только что назвал мой SearchBar. в) из viewDidLoad вы хотите получить текстовое поле внутри панели поиска. Я сделал это так.

UITextField *textField = [self.searchBar valueForKey:@"_searchField"];
if (textField) {
    textField.delegate = self;
    textField.tag = 1000;
}

Обратите внимание, я назначил тег для этого textField, чтобы я мог его снова захватить, и сделал его делегатом textField. Вы могли бы создать свойство и назначить этому textField это свойство, чтобы получить его позже, но я использовал тег.

Здесь вам просто нужно вызвать метод делегата:

-(BOOL)textFieldShouldClear:(UITextField *)textField {
if (textField.tag == 1000) {
    // do something
    return YES;
}
return NO;

}

Вот и все. Поскольку вы имеете в виду частное значениеForKey, я не могу гарантировать, что оно не доставит вам неприятностей.

1 голос
/ 26 января 2010

Я бы предложил использовать методы rightView и rightViewMode UITextField для создания собственной кнопки очистки, которая использует то же изображение. Конечно, я предполагаю, что UISearchBar позволит вам получить доступ к UITextField внутри него. Я думаю, что это будет.
Помните об этом из справочной библиотеки iPhone OS:

If an overlay view overlaps the clear button, however, the clear button always takes precedence in receiving events. By default, the right overlay view does overlap the clear button.

Так что вам, вероятно, также понадобится отключить исходную кнопку очистки.

0 голосов
/ 03 октября 2014

Не удалось найти здесь решение, которое бы не использовало частный API или не было доказательством обновления, если Apple изменила структуру представления UISearchBar. Вот что я написал, что работает:

- (void)viewDidLoad {
    [super viewDidLoad];

    UITextField* textfield = [self findTextFieldInside:self.searchBar];
    [textfield setDelegate:self];
}

- (UITextField*)findTextFieldInside:(id)mainView {
    for (id view in [mainView subviews]) {
        if ([view isKindOfClass:[UITextField class]]) {
            return view;
        }

        id subview = [self findTextFieldInside:view];
        if (subview != nil) {
            return subview;
        }
    }

    return nil;
}

Затем внедрите протокол UITextFieldDelegate в свой класс и перезапишите textFieldShouldClear: метод.

- (BOOL)textFieldShouldClear:(UITextField*)textField {
    // Put your code in here.
    return YES;
}

Редактировать: Установка делегата в текстовое поле панели поиска в iOS8 приведет к сбою. Однако похоже, что searchBar: textDidChange: метод будет вызван на iOS8 в открытом виде.

0 голосов
/ 10 марта 2014

Лучшее решение из моего опыта - просто поместить UIButton (с чистым фоном и без текста) над кнопкой очистки системы, а затем подключить IBAction

- (IBAction)searchCancelButtonPressed:(id)sender {

    [self.searchBar resignFirstResponder];
    self.searchBar.text = @"";

    // some of my stuff
    self.model.fastSearchText = nil;
    [self.model fetchData];
    [self reloadTableViewAnimated:NO];

}
...