When assigning focus via becomeFirstResponder to UISearchController's UISearchBar, the keyboard does not appear

放肆的年华 提交于 2019-11-28 20:13:47

Your code looks ok. What you are describing isn't normal behaviour. The first thing you can do is to create a new project with just the UISearchController functionality and see how it goes. You can edit your question with it so we'll have a better view.

There's a good example on how to implement UISearchController here: Sample-UISearchController

Adding:

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

to MasterViewController_TableResults.m gave the expected results and the keyboard popped up on launch on an iPad & iPhone with iOS 8.3.

You can go over that project and see what you did differently,

Edit:

Apparently if [self.searchController setActive:YES] is called before becomeFirstResponder the keyboard won't show. I wonder if that's a bug or not.

emn.mun

Had the same annoying issue. You would think that by setting the SearchController as active would both present the the search controller and the keyboard. Unfortunately, it only does the first part.

My solution

  • in viewDidAppear make the Search Controller active:

    override func viewDidAppear(animated: Bool) {
      super.viewDidAppear(animated)
      resultSearchController.active = true 
    }
    
  • once it is active, in didPresentSearchController make as first responder

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

Swift 3.0 (iOS 10) working solution:

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        searchController.isActive = true
        DispatchQueue.main.async { [unowned self] in
            self.searchController.searchBar.becomeFirstResponder()
        }
    }

On iOS 9 I've found its sufficient to delay becomeFirstResponder() to the next run loop:

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

Working Solution:-

Don't use [self.searchController setActive:YES] before becomeFirstResponder.

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

In iOS 10, I had to run the code in delegate method on main thread. First I set the active to YES in viewDidAppear,

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

The solution that will work is as follows :

1.Override ViewDidLayoutSubviews in the view controller in which you are showing UISearchController

2.Override ViewDidLayoutSubviews and inside it make search bar first responder.

Tested it on iOS > 9.0

Caution : Put a null check before making it First responder as follows

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

This is because ViewDidLayoutSubviews also gets called when cancel button is pressed.

This worked for me in Xamarin.

Sociopathe

I had trouble with an UISearchBar not displaying the keyboard when doing

[searchBar becomeFirstResponder];

By searching on the net, i found this thread on the Apple developer website that helped me to discover that the keyboard won't open if you don't have a keyWindow.

The application i work on do something like this :

  1. Window A (KeyWindow)
  2. do some things
  3. open Window B (KeyWindow)
  4. do some things
  5. close Window B (resign KeyWindow)

I just had to do

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

after the resigning of window B and no more trouble with the keyboard.

Özgür

This might also be related to Simulator Settings. Just disable Hardware -> Keyboard -> "Connect Hardware Keyboard" .

For further details: UISearchBar not showing keyboard when tapped

-(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];
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!