Подтвердить что ты не робот

При назначении фокуса с помощью startFirstResponder в UISearchController UISearchBar клавиатура не появляется

Я потратил немало времени на поиск в Интернете и разговоры с другими разработчиками об этой проблеме безрезультатно. Точная проблема описана в этом сообщении 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;
}

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

  • Я пробовал называть startFirstResponder с задержкой в ​​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.

4b9b3361

Ответ 1

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

Вот хороший пример того, как реализовать UISearchController здесь: Sample-UISearchController

Добавление:

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

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

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

Edit:

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

Ответ 2

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

Мое решение

  • В режиме просмотраDidAppear активный контроллер поиска:

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

    func didPresentSearchController(searchController: UISearchController) {
      searchController.searchBar.becomeFirstResponder() 
    }
    

Ответ 3

Рабочее решение 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()
        }
    }

Ответ 4

В 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()
    })
}

Ответ 5

В iOS 10 мне пришлось запустить код в методе делегата в основном потоке. Сначала я установил активный в YES в 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];
  });
}

Ответ 6

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

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

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

Ответ 7

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

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

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

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

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

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

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

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

Ответ 8

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

[searchBar becomeFirstResponder];

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

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

  • Окно A (KeyWindow)
  • сделать некоторые вещи
  • открыть окно B (KeyWindow)
  • сделать некоторые вещи
  • закрыть окно B (отменить KeyWindow)

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

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

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

Ответ 10

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

//and then in the delegate method:

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

//The above works for me in addition to this I had to add:
-(void)viewWillDisappear:(BOOL)animated {
    [searchController setActive:NO];
}