При назначении фокуса UISearchBar UISearchController через статьFirstResponder клавиатура не отображается

Я потратил довольно много времени на поиск в Интернете и безрезультатно разговаривал с другими разработчиками об этой проблеме. Точная проблема описана в этом сообщении SO (Сосредоточьтесь на UISearchBar но клавиатура не появляется), хотя ей много лет.

Недавно я перешел с использования устаревших UISearchDisplayController и UISearchBar в IB и перешел на UISearchController через код для iOS8.

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

Вот код, который у меня есть.

.h

@property (nonatomic, strong) UISearchController *searchController;

.m

- (void)viewDidLoad {
    [super viewDidLoad];
    ...
    [self initializeSearchController];
    ....
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.searchController setActive:YES];
    [self.searchController.searchBar becomeFirstResponder];
}

- (void)initializeSearchController {
    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
    self.searchController.searchResultsUpdater = self;
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.searchController.delegate = self;
    self.searchController.searchBar.delegate = self;
    [self.searchController.searchBar sizeToFit];

    [self.tableView setTableHeaderView:self.searchController.searchBar];
    self.definesPresentationContext = YES;
}

То, что я пробовал до сих пор.

  • Я пробовал вызвать статьFirstResponder с задержкой в ​​0,2 секунды, как это было предложено в другом сообщении SO.

  • Я установил точку останова в viewDidAppear и убедился, что как self.searchController, так и self.searchController.searchBar являются допустимыми объектами, а не nil.

  • Я пробовал соответствовать UISearchControllerDelegate и использовать следующий фрагмент кода

здесь:

- (void)didPresentSearchController:(UISearchController *)searchController {
    //no matter what code I put in here to becomeFirstResponder, it doesn't
    //matter because this is never called, despite setting the     
    //self.searchController.delegate = self AND 
    //self.searchController.searchBar.delegate = self.
}
  • Я создал новое представление с нуля в раскадровках и перешел к нему, чтобы убедиться, что в моем представлении нет какого-то старого остатка searchBar. Это тоже не сработало.

  • Я тестировал это только на реальном устройстве (iPhone 6), и это не проблема симулятора, когда не отображается клавиатура.

У меня нет идей, и я видел все вопросы и ответы, связанные с этим, в Интернете. Ничего не работает.

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


person chris P    schedule 29.05.2015    source источник
comment
Вы тестировали это на реальном устройстве? Если эта проблема возникает в симуляторе, попробуйте нажать ⌘K (command-k), чтобы открыть клавиатуру.   -  person benhameen    schedule 29.05.2015
comment
@benhameen Да, я тестировал это только на своем iPhone 6.   -  person chris P    schedule 29.05.2015


Ответы (9)


Ваш код выглядит нормально. То, что вы описываете, ненормальное поведение. Первое, что вы можете сделать, - это создать новый проект только с UISearchController функциями и посмотреть, как он пойдет. Вы можете отредактировать свой вопрос с его помощью, чтобы мы могли лучше рассмотреть.

Вот хороший пример реализации UISearchController: Sample-UISearchController

Добавление:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self.searchController.searchBar becomeFirstResponder];
}

to MasterViewController_TableResults.m дал ожидаемые результаты, и клавиатура появилась при запуске на iPad и iPhone с iOS 8.3.

Вы можете просмотреть этот проект и посмотреть, что вы сделали по-другому,

Изменить:

Очевидно, если [self.searchController setActive:YES] вызывается до becomeFirstResponder, клавиатура не будет отображаться. Интересно, ошибка это или нет.

person Segev    schedule 28.06.2015
comment
Обратите внимание, что вопрос не о (устаревшем) UISearchDisplayController - person Felix; 29.06.2015
comment
В проекте по ссылке используется UISearchController. извините за опечатку. (фиксированный) - person Segev; 29.06.2015
comment
Это сработало! Странно то, что клавиатура не появляется, когда перед этим вызывается [self.searchController setActive: YES], как и код в вопросе. - person Felix; 29.06.2015
comment
Интересный. Интересно, ошибка это или нет. Рад, что вы нашли проблему. Я отредактирую свой ответ с учетом ваших выводов. - person Segev; 29.06.2015
comment
Я попытался поставить вызов, чтобы активировать контроллер поиска после вызова, чтобы панель поиска стала первым респондентом. У меня все еще не работает. Я использую это вместе с контроллером навигации. Не уверен, что в этом разница. - person Jeremy Hicks; 26.09.2015

Была такая же досадная проблема. Можно подумать, что установка SearchController в качестве активного представит и контроллер поиска, и клавиатуру. К сожалению, это только первая часть.

Мое решение

  • в viewDidAppear активируйте контроллер поиска:

    override func viewDidAppear(animated: Bool) {
      super.viewDidAppear(animated)
      resultSearchController.active = true 
    }
    
  • как только он станет активным, в didPresentSearchController сделайте его первым респондентом

    func didPresentSearchController(searchController: UISearchController) {
      searchController.searchBar.becomeFirstResponder() 
    }
    
person emn.mun    schedule 02.07.2015
comment
у меня не работает. didPresentSearchController вызывается, но клавиатура не появляется. - person Felix; 03.07.2015
comment
У меня это сработало, хотя во втором примере кода, похоже, была небольшая опечатка (я отправлю исправление для него). Я бы предпочел, чтобы контроллер стал активным и клавиатура появилась одновременно, но пока этого хватит. - person Garrett Albright; 04.07.2015
comment
У меня тоже работает на iOS9. Очень неприятная проблема. Я был на грани отказа. Спасибо. - person AXE; 12.09.2015
comment
Кто-нибудь знает, почему это не работает на iOS9, когда панель поиска находится в панели навигации? - person Valentin; 21.09.2015
comment
@Valentin, у меня это работает только тогда, когда я делаю панель поиска первым респондентом в основном потоке: dispatch_async(dispatch_get_main_queue(), { searchController.searchBar.becomeFirstResponder() }) - person vinsanity555; 08.01.2016

Рабочее решение Swift 3.0 (iOS 10):

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        searchController.isActive = true
        DispatchQueue.main.async { [unowned self] in
            self.searchController.searchBar.becomeFirstResponder()
        }
    }
person Tendai Moffatt    schedule 12.10.2016
comment
У меня не работает. Моя панель поиска находится на панели навигации. Не знаю, имеет ли это что-нибудь или нет. - person Bagusflyer; 31.10.2016
comment
Не уверен, что это самое чистое решение, но у меня оно сработало. Спасибо! - person Cesare; 08.12.2016
comment
У меня это работает в iOS 11, за исключением набора isActive, другие вышеперечисленные решения не помогли. - person C. Bess; 29.09.2017

В iOS 9 я обнаружил, что этого достаточно, чтобы отложить becomeFirstResponder() до следующего цикла выполнения:

func focusSearchField() {
    searchController?.active = true

    // skipping to the next run loop is required, otherwise the keyboard does not appear
    dispatch_async(dispatch_get_main_queue(), { [weak self] in
        self?.searchController?.searchBar.becomeFirstResponder()
    })
}
person jszumski    schedule 12.01.2016
comment
Единственное, что у меня сработало на iOS 9. Вы можете использовать [unowed self] и прочитать распаковку self. ИМХО здесь чище и безопаснее. - person tonymontana; 08.06.2016

Рабочее решение: -

Не используйте [self.searchController setActive: YES] перед тем, как статьFirstResponder.

- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   dispatch_async(dispatch_get_global_queue(0, 0), ^{
    dispatch_async(dispatch_get_main_queue(), ^{
       // [self.searchController setActive:YES];
        [self.searchController.searchBar becomeFirstResponder];
     });
 });
}
person Jain_Taresh    schedule 22.06.2017
comment
У меня работало в iOS 11. - person SAHM; 18.11.2017

В iOS 10 мне приходилось запускать код в методе делегата в основном потоке. Сначала я установил активный параметр на ДА в viewDidAppear,

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
      [self.searchController setActive:YES];
}

а затем в методе делегата:

- (void)didPresentSearchController:(UISearchController *)searchController
{
  dispatch_async(dispatch_get_main_queue(), ^{
  [searchController.searchBar becomeFirstResponder];
  });
}
person Teja Nandamuri    schedule 23.09.2016

Решение, которое будет работать, выглядит следующим образом:

1.Переопределите ViewDidLayoutSubviews в контроллере представления, в котором вы показываете UISearchController

2. Отмените ViewDidLayoutSubviews и внутри него сделайте поисковую строку первым респондентом.

Тестировал на iOS> 9.0

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

if((searchController != null)&&(searchController.SearchBar != null))
            searchController.SearchBar.BecomeFirstResponder();

Это потому, что ViewDidLayoutSubviews также вызывается при нажатии кнопки отмены.

Это сработало для меня в Xamarin.

person user3106871    schedule 09.06.2016

У меня была проблема с UISearchBar, не отображавшим клавиатуру при выполнении

[searchBar becomeFirstResponder];

Путем поиска в сети я нашел эту ветку на Apple веб-сайт разработчика, который помог мне обнаружить, что клавиатура не открывается, если у вас нет keyWindow.

Приложение, над которым я работаю, делает что-то вроде этого:

  1. Окно A (KeyWindow)
  2. делать некоторые вещи
  3. открыть окно B (KeyWindow)
  4. делать некоторые вещи
  5. закрыть окно B (отказаться от KeyWindow)

Мне просто нужно было сделать

[[[[UIApplication sharedApplication] windows] firstObject] makeKeyWindow];

после отставки окна B и проблем с клавиатурой больше нет.

person Sociopathe    schedule 19.10.2015

Это также может быть связано с настройками симулятора. Просто отключите Оборудование -> Клавиатура -> «Подключить аппаратную клавиатуру».

Для получения дополнительных сведений: UISearchBar не показывает клавиатуру при нажатии

person Özgür    schedule 08.02.2016