Могу ли я подключиться к кнопке Очистки UISearchBar в UISearchBar?

StackOverflow https://stackoverflow.com/questions/925221

Вопрос

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

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

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

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

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

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

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

Две проблемы, которые, однако, возникают:

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

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

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

Спасибо!

Это было полезно?

Решение

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

UISearchBar clearButton вызывает отображение клавиатуры

Лучшие

Другие советы

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

- (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];   
}

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

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    if ([searchBar.text isEqualToString:@""]) {
        //Clear stuff here
    }
}

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

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

func hideKeyboardWithSearchBar(bar:UISearchBar) {
    bar.resignFirstResponder()
}

Я бы предложил использовать 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.

Поэтому вам, вероятно, также потребуется отключить оригинальную кнопку очистки.

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

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

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

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

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

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

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

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

}

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

Вы могли бы попробовать это:

- (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;
}

Лучшее решение из моего опыта - просто поместить 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];

}

Не удалось найти здесь решение, которое не использовало бы частный 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 приведет к аварийному завершению работы.Однако это выглядит как строка поиска:textDidChange:метод будет вызван в iOS8 при очистке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top