Выполните действие на UISearchBar, когда клавиатура не работает, а x был нажат

У меня есть UITableView с UISearchBar сверху и есть конкретное требование, которое не работает.

У меня нет кнопки Отмена на моем UISearchBar (showsCancelButton = NO) поэтому я полностью полагаюсь на х в UISearchBar отменить существующий поиск. Я полагаюсь на кнопку "Поиск" на клавиатуре, чтобы закрыть клавиатуру (хотя в моем случае она называется "Готово").

Когда пользователь выполняет поиск в моем приложении, я отключаю navigation bar button элемент, потому что он дает плохой пользовательский опыт, и только после того, как поиск был отменен, пользователь возвращает элемент кнопки панели навигации обратно. Это все работает.

У меня есть один конкретный сценарий, который я не могу обойти.

1) Нажмите на строку поиска, чтобы ввести текст

2) Нажмите DONE на клавиатуре, и клавиатура исчезнет

3) С клавиатурой в отставке, х остается в UISearchBar

4) Нажмите х в UISearchBar и текст в SearchBar исчезает и вид обновляется

5) На этом этапе кнопка панели навигации должна быть снова включена, но это не так.

Код:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    self.timelineSearchBar.showsCancelButton = NO;
    if ([searchText length] == 0)
    {
        [self.timelineSearchBar performSelector:@selector(resignFirstResponder)
                    withObject:nil
                  afterDelay:0];
    }

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

В моем случае клавиатура уже ушла в отставку, поэтому я хочу, чтобы нажатие на x снова включило элемент панели навигации.

    self.addButton.enabled = YES; 

в том случае, если приведенный выше оператор вообще ничего не делает, а элемент панели навигации по-прежнему отключен.

Я даже пытался в этом, если заявление:

[self.timelineSearchBar performSelector:@selector(enableAdd)
                    withObject:nil
                  afterDelay:0];

- (void)enableAdd
{
    self.addButton.enabled = YES;
}

но это дает сбой, говоря, что searchBar не отвечает на этот селектор enableAdd.

Я сделал точку останова и вижу, что оператор if, приведенный выше, действительно принимает значение true, когда я нажимаю x, и он входит в оператор, он "запускает" код для включения кнопки, но этого не происходит.

Также мой конечный метод редактирования:

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    [searchBar setShowsCancelButton:NO animated:YES];
    self.addButton.enabled = YES;
}

ОБНОВЛЕНИЕ: я попробовал ссылку здесь http://engineeringtheworld.wordpress.com/2011/04/11/detecting-when-clear-is-clicked-in-uisearchbar-x-button/ безуспешно - textField должен очистить метод не вызывается. Я использую iOS 7, так что, возможно, есть еще один способ встроить представления с textFields? Возможно, это правильный подход, но он не работает с моим кодом, потому что оператор for в этом примере никогда не будет оценен как true (я добавил NSLog).

ОБНОВЛЕНИЕ 2: Из приведенного выше оператора if я вызвал метод searchBarCancelButton, и у меня возникли экстремальные циклы, так что, конечно, это был неправильный подход:

[self performSelector:@selector(searchBarCancelButtonClicked:) withObject:self.timelineSearchBar afterDelay: 0];

Любое руководство по этому вопросу будет оценено. Я знаю, что пропускаю ключевой шаг, но я просто не могу понять это.

3 ответа

Решение

Проблема в том, что при нажатии на кнопку X, searchBar:textDidChange: называется раньше searchBarShouldBeginEditing:

т.е. вот поток вызовов: searchBar:textDidChange: -> searchBarShouldBeginEditing: -> searchBarTextDidBeginEditing: -> searchBarTextDidEndEditing:

textDidChange настройка включена на ДА, но затем shouldBeginEditing отключает его снова. Это прекрасно работает для меня:

-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    self.addButton.enabled = NO;
}

-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    if(searchBar.text.length == 0){
        self.addButton.enabled = YES;
    }
}

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

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    self.addButton.enabled = [searchBar.text length] == 0;
    [searchBar resignFirstResponder];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if([searchText length] == 0 && searchBar.text.length == 0)
    {
        self.addButton.enabled = YES;
        [searchBar performSelector: @selector(resignFirstResponder)
                    withObject: nil
                    afterDelay: 0.1];
    }
}

Я создаю здесь ответ для ясности, но ответ Майклса очень помог, и здесь принят подход, хотя мой код работал.

Я много копался с NSLogs и что интересно, я обнаружил, что shouldBeginEditing появился перед textDidChange (в порядке NSLogs).

Тем не менее, я также заметил, что на этапах в моем исходном вопросе, с отклоненной клавиатурой и UISearchBar, содержащим текст и видимый x, если я коснулся x, клавиатура не появилась, но она вызвала shoudlBeginEditing снова.

Это был метод, который заставлял addButton оставаться серым, потому что этот метод устанавливал эту кнопку как отключенную.

Поэтому я скорректировал код:

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)bar
{
    NSLog(@"Should begin");
    if ([self.timelineSearchBar.text length] > 0)
    {
        self.addButton.enabled = NO;
    }
    else
    {
        self.addButton.enabled = YES;
    }
    self.timelineSearchBar.showsCancelButton = NO;
    BOOL boolToReturn = self.shouldBeginEditing;
    self.shouldBeginEditing = YES;
    return boolToReturn;
}

Я поместил туда условие if, чтобы код реагировал соответствующим образом, если я вернулся к панели поиска после отмены с помощью x.

Таким образом, кнопка добавления не отключается, как только я нажимаю на UISearchBar (который поднимает клавиатуру). Однако в textDidChange (то, что я видел, вызывается с самой первой набираемой буквы), я также поставил следующее условие:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    NSLog(@"Text did change");
    self.timelineSearchBar.showsCancelButton = NO;
    if ([self.timelineSearchBar.text length] > 0)
    {
        self.addButton.enabled = NO;
    }
...
}

Таким образом, UISearchBar будет только отображать кнопку добавления, когда я начну вводить буквы. Это сработало для меня, потому что если пользователь нажал на UISearchBar и ничего не набрал, в prepareForSegue что дошло до того, что Add Entry вызывал, я проверил, если searchBar isFirstResponder и если да, то я resignFirstResponder,

Имея это в виду, я не уверен, что это способ Apple, но он чистый. Я скоро узнаю, будет ли мое приложение отклонено из-за этого, но большое спасибо за вашу помощь Майклз; Вы действительно указали мне правильное направление для решения проблемы, которая занимала весь мой день!

Другие вопросы по тегам