通过becomeFirstResponder将焦点分配给UISearchController的UISearchBar时,键盘不显示

时间:2015-05-29 05:52:18

标签: ios objective-c keyboard uisearchbar uisearchcontroller

我花了很多时间在网上搜索并与其他开发者讨论这个问题无济于事。这个SO帖子(Focus on the UISearchBar but the keyboard not appear)中描述了确切的问题,尽管它已经存在了很多年。

我最近在IB中使用了已弃用的UISearchDisplayController和UISearchBar,并通过iOS8的代码切换到UISearchController。

然而,我遇到的问题是焦点是否正确分配(您可以判断,因为视图加载后取消按钮会在搜索栏的右侧显示动画),但键盘不会显示。< / p>

这是我的代码。

·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;
}

到目前为止我尝试过的事情。

  • 我已经尝试在0.2秒的延迟时间内调用yesFirstResponder,如另一篇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中闪烁。

10 个答案:

答案 0 :(得分:20)

您的代码看起来不错。你所描述的并不是正常行为。 您可以做的第一件事是创建一个只有UISearchController功能的新项目,看看它是如何运作的。您可以使用它编辑您的问题,以便我们有更好的观点。

这里有一个关于如何实施UISearchController的好例子:Sample-UISearchController

添加:

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

MasterViewController_TableResults.m给出了预期的结果,并且在iPad和iPad上发布时弹出了键盘。带iOS 8.3的iPhone。

您可以查看该项目,看看您的行为有何不同,

修改

显然,如果[self.searchController setActive:YES]becomeFirstResponder之前调出,则键盘不会显示。我想知道这是不是一个错误。

答案 1 :(得分:19)

有同样烦人的问题。 你会认为通过将SearchController设置为活动状态,它们都会显示搜索控制器和键盘。不幸的是,它只是第一部分。

我的解决方案

    viewDidAppear中的
  • 使搜索控制器处于活动状态:

    override func viewDidAppear(animated: Bool) {
      super.viewDidAppear(animated)
      resultSearchController.active = true 
    }
    
  • 一旦激活,在didPresentSearchController中作为第一响应者

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

答案 2 :(得分:12)

Swift 3.0(iOS 10)工作解决方案:

function display_person( $atts ) {
    $atts = shortcode_atts( array(
        'id' => false,
        'name' => false
    ), $atts, 'person' );


    if ( $atts['id'] ) {
        $person = get_post( $atts['id'] );
    } else if ( $atts['name'] ) {
        // todo
    }

    $image = get_the_post_thumbnail( $person->ID, 'medium' );
    $name = $person->post_title;
    $content = wpautop( $person->post_content );

    $output = ""; // todo


    return $output;
}
add_shortcode( 'person', 'display_person' );

答案 3 :(得分:7)

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

答案 4 :(得分:3)

工作解决方案: -

在使用firstFirstResponder之前不要使用[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];
     });
 });
}

答案 5 :(得分:2)

可行的解决方案如下:

1.在显示ViewDidLayoutSubviews的视图控制器中取消UISearchController

2.Override ViewDidLayoutSubviews并在其内部使搜索栏成为第一响应者。

在iOS上测试&gt; 9.0

注意:在进行第一响应之前进行空检查,如下所示

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

这是因为按下取消按钮时也会调用ViewDidLayoutSubviews

这对Xamarin来说很有用。

答案 6 :(得分:2)

在iOS 10中,我必须在主线程上的委托方法中运行代码。首先,我将viewDidAppear中的active设置为YES,

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

然后在委托方法中:

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

答案 7 :(得分:0)

我在使用

时没有显示键盘的UISearchBar时遇到了麻烦
[searchBar becomeFirstResponder];

通过在网上搜索,我在Apple开发者网站上找到了这个thread 这让我发现如果你没有钥匙窗口,键盘就会打开。

我正在处理的应用程序执行以下操作:

  1. 窗口A(KeyWindow)
  2. 做一些事情
  3. 打开Window B(KeyWindow)
  4. 做一些事情
  5. 关闭窗口B(辞职KeyWindow)
  6. 我只需要做

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

    在窗口B退出后,键盘没有问题。

答案 8 :(得分:0)

这也可能与模拟器设置有关。只需禁用硬件 - &gt;键盘 - &gt; &#34;连接硬件键盘&#34;

有关详细信息:UISearchBar not showing keyboard when tapped

答案 9 :(得分:0)

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