Отключение клавиатуры от UISearchBar при нажатии кнопки X - PullRequest
18 голосов
/ 16 ноября 2010

Я использую UISearchBar (но не SearchDisplayController, который обычно используется в сочетании), и я хотел бы отключить клавиатуру, когда вы нажмете кнопку «X».

Я следовал Предложение TomSwift о вызове, когда нажимается 'X', и это прекрасно работает.Но отставка первого респондента из текстового поля, а также вызов в экземпляре UISearchBar, оба с resignFirstResponder, не заставят клавиатуру исчезнуть.

Есть ли способ избавиться от клавиатуры, когда пользователь нажал кнопку X?

Вот что я сделал, чтобы получить уведомление «Очистить»:

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

Затем у меня есть настройки класса для реализации UISearchBarDelegate и UITextFieldDelegate.

Наличие класса serveпоскольку делегат текстового поля позволяет мне получить этот вызов:

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
     [textField resignFirstResponder];
     [self.searchBar resignFirstResponder];
     return YES;
}

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

Ответы [ 13 ]

71 голосов
/ 31 января 2012

Томс ответ заставил меня задуматься. Если это так, что панель поиска еще не является firstResponder, когда пользователь нажимает кнопку очистки, мы можем просто подождать, пока она не появится, и затем получить ее resignFirstResponder; то есть в соответствии с:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
  [self performFilteringBySearchText: searchText]; // or whatever

  // The user clicked the [X] button or otherwise cleared the text.
  if([searchText length] == 0) {
    [searchBar performSelector: @selector(resignFirstResponder) 
                    withObject: nil 
                    afterDelay: 0.1];
  }
}

Работает как шарм и менее хакерски, чем ИМХО Тома.

6 голосов
/ 21 марта 2013

Это работает:

[searchBar performSelector:@selector(resignFirstResponder) withObject:nil afterDelay:0.1];
4 голосов
/ 25 марта 2017

Обновлено для SWIFT 3:

Предположим, что пользователь ввел строку в поле поиска и нажимает x, следующий код работает, чтобы скрыть клавиатуру при нажатии x

`

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
{
            if searchBar.text == nil || searchBar.text == ""
            {
                searchBar.perform(#selector(self.resignFirstResponder), with: nil, afterDelay: 0.1)
            }
 }

`

3 голосов
/ 01 ноября 2015

Swift 2 версия:

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
        // The user clicked the [X] button or otherwise cleared the text.
        if (searchText.characters.count == 0) {
            searchBar.performSelector("resignFirstResponder", withObject: nil, afterDelay: 0.1)
        }
    }
2 голосов
/ 17 ноября 2010

Обновление:

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

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

// this in the context of the search bar
- (UIButton*) cancelButton
{
    for (UIView* v in self.subviews)
    {
        if ( [v isKindOfClass: [UIButton class]] )
            return (UIButton*)v;
    }

    return nil;
}

// this is the textField delegate callback
- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    [textField resignFirstResponder];

    UIButton* cb = _searchBar.cancelButton;

    NSObject* target = [[cb allTargets] anyObject];

    NSArray* actions = [cb actionsForTarget: target forControlEvent:UIControlEventTouchUpInside];

    NSString* selectorName = [actions  objectAtIndex:0];

    SEL selector = NSSelectorFromString( selectorName );

    [target performSelector: selector withObject: cb afterDelay: 0.1];

    return YES;
}

Оригинальный ответ:

Как вы получаете кнопку «Х» для отображения в первую очередь? В моем тестовом случае я не вижу его отображения ...

Попробуйте выполнить resignFirstResponder в строке поиска, а не в текстовом поле.

2 голосов
/ 16 ноября 2010

Вы можете resignFirstResponder по нажатию кнопки отмены как.

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar

{

    SearchBar.showsCancelButton =NO;

}


- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{

    [SearchBar resignFirstResponder];


}
1 голос
/ 18 февраля 2014

Не следует ли вносить изменения в пользовательский интерфейс в основном потоке вместо использования performselector:WithObject:afterDelay:?

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if (searchText.length == 0) {
        [searchBar performSelectorOnMainThread:@selector(resignFirstResponder) withObject:nil waitUntilDone:NO];
    }
}
1 голос
/ 08 декабря 2012

Я использовал комбинацию ответа @ radiospiel и ответа, который @Tozar связал с:

@interface SearchViewController : UIViewController <UISearchBarDelegate> {
    // all of our ivar declarations go here...
    BOOL shouldBeginEditing;
    ....
}

...
@end

@implementation SearchViewController
...
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        ...
        shouldBeginEditing = YES;
    }
}
...

- (void) searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
    // TODO - dynamically update the search results here, if we choose to do that.

    if (![searchBar isFirstResponder]) {
        // The user clicked the [X] button while the keyboard was hidden
        shouldBeginEditing = NO;
    }
    else if ([searchText length] == 0) {
        // The user clicked the [X] button or otherwise cleared the text.
        [theSearchBar performSelector: @selector(resignFirstResponder)
                        withObject: nil
                        afterDelay: 0.1];
    }
}

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)bar {
    // reset the shouldBeginEditing BOOL ivar to YES, but first take its value and use it to return it from the method call
    BOOL boolToReturn = shouldBeginEditing;
    shouldBeginEditing = YES;
    return boolToReturn;
}
@end
1 голос
/ 22 марта 2012

Старайтесь избегать

- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar

метода в вашем коде, мы можем решить эту проблему

1 голос
/ 16 ноября 2010

Я нашел это в предыдущем вопросе:

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

Она должна делать именно то, что вы хотите.

...