Ios 显示UISearchController';s SearchResultsController在搜索栏点击

Ios 显示UISearchController';s SearchResultsController在搜索栏点击,ios,uisearchcontroller,Ios,Uisearchcontroller,我使用的是UISearchController而不是UISearchDisplayController,我想立即在搜索栏上显示SearchResultController。现在显示如下(当我点击搜索栏时): 当结果为空时,UISearchController的viewController仍然隐藏。这就是为什么我们必须使用UISearchControllerDelegate的willPresentSearchController: 初始化self.searchController后,使您的View

我使用的是UISearchController而不是UISearchDisplayController,我想立即在搜索栏上显示SearchResultController。现在显示如下(当我点击搜索栏时):


当结果为空时,
UISearchController
viewController
仍然隐藏。这就是为什么我们必须使用
UISearchControllerDelegate
willPresentSearchController:

初始化self.searchController后,使您的ViewController符合“UISearchControllerDelegate: 在ViewController中实现
将显示SearchController:
: 异步调度是必要的,因为否则它将被内部行为覆盖。您可以在这里使用动画来淡入表格视图

此外,为确保安全,请实施
didPresentSearchController:
: 我认为这种方法更好,当搜索栏为空时,小心预加载tableview会再次消失

UISearchBarDelegate UISearchControllerDelegate
我发现其他答案由于使用
dispatch\u async
而闪烁。他们使用此选项,以便在搜索控制器的内部行为完成后应用他们的更改,但这会在覆盖内部行为之前留下几个应用内部行为的框架。使用KVO允许我立即覆盖内部行为,而不会出现任何闪烁

我还发现,当用户点击按钮时,其他答案并不能使搜索结果控制器保持可见ⓧ 按钮以清除搜索栏的内容,我觉得这似乎不正确

- (void) viewDidLoad
{
    ...
    self.searchController.delegate = self;
    [self.searchController.searchResultsController.view addObserver:self forKeyPath:@"hidden" options:0 context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{    
    if ( object == self.searchController.searchResultsController.view &&
         [keyPath isEqualToString:@"hidden"] &&
         self.searchController.searchResultsController.view.hidden &&
         self.searchController.searchBar.isFirstResponder )
    {
        self.searchController.searchResultsController.view.hidden = NO;
    }
}

- (void) willPresentSearchController:(UISearchController *)searchController
{
    searchController.searchResultsController.view.hidden = NO;
}

- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if ( searchText.length == 0 )
        self.searchController.searchResultsController.view.hidden = NO;
}


- (void) searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    self.searchController.searchResultsController.view.hidden = YES;
}

Chris Vasselli的答案是实现这一点的最干净的方法

这里是Swift 3

override func viewDidLoad() {
    super.viewDidLoad()

    searchController.delegate = self
    self.searchController.searchResultsController?.view.addObserver(self, forKeyPath: "hidden", options: [], context: nil)
}


override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

    if let someView: UIView = object as! UIView? {

        if (someView == self.searchController.searchResultsController?.view &&
            (keyPath == "hidden") &&
            (searchController.searchResultsController?.view.isHidden)! &&
            searchController.searchBar.isFirstResponder) {

            searchController.searchResultsController?.view.isHidden = false
        }

    }
}


func willPresentSearchController(_ searchController: UISearchController) {
    searchController.searchResultsController?.view.isHidden = false
}


func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    if (searchText.characters.count == 0) {
        searchController.searchResultsController?.view.isHidden = false
    }
}


func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
    searchController.searchResultsController?.view.isHidden = true
}

它仅在第一次从搜索结果控制器中点击任何内容时才起作用。当您再次点击搜索栏时,它不会显示搜索结果控制器。您是否尝试实现计数器委托方法
diddissearchcontroller:
willdisissearchcontroller:
?设置这些方法的内部
searchController.searchResultsController.view.hidden=YES。我这样做了,但对它没有任何影响。我无法用示例代码()复制它。第二次点击时是否调用委托方法?@tubtub这对于第一次启动非常有效。如果我们键入一些内容,然后完全删除输入的文本,那么resultsController将再次隐藏。有没有办法解决这个问题?到目前为止,这是最有效的答案。“观察者”是关键(双关语的含蓄)谢谢你提供了一个很好的解决方案!但是我可以问你,如果你已经为此目的设置了一个观察者,为什么你要处理searchBar:textDidChange方法?我已经有一段时间没有看到这个了,但是看起来观察者只处理不断变化的“hidden”属性,而searchBar:textDidChange:检测文本的最后一位何时被删除,并隐藏搜索结果控制器。看起来他们完成了两件不同的事情。
- (void)didPresentSearchController:(UISearchController *)searchController
{
    searchController.searchResultsController.view.hidden = NO;
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
    if searchText.isEmpty {
        dispatch_async(dispatch_get_main_queue()) {
            self.searchController.searchResultsController?.view.hidden = false
        }
    }
}

func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
    dispatch_async(dispatch_get_main_queue()) {
        self.searchController.searchResultsController?.view.hidden = false
    }
}
func willPresentSearchController(searchController: UISearchController) {
    dispatch_async(dispatch_get_main_queue()) {
        self.searchController.searchResultsController?.view.hidden = false
    }
}
- (void) viewDidLoad
{
    ...
    self.searchController.delegate = self;
    [self.searchController.searchResultsController.view addObserver:self forKeyPath:@"hidden" options:0 context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{    
    if ( object == self.searchController.searchResultsController.view &&
         [keyPath isEqualToString:@"hidden"] &&
         self.searchController.searchResultsController.view.hidden &&
         self.searchController.searchBar.isFirstResponder )
    {
        self.searchController.searchResultsController.view.hidden = NO;
    }
}

- (void) willPresentSearchController:(UISearchController *)searchController
{
    searchController.searchResultsController.view.hidden = NO;
}

- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if ( searchText.length == 0 )
        self.searchController.searchResultsController.view.hidden = NO;
}


- (void) searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    self.searchController.searchResultsController.view.hidden = YES;
}
override func viewDidLoad() {
    super.viewDidLoad()

    searchController.delegate = self
    self.searchController.searchResultsController?.view.addObserver(self, forKeyPath: "hidden", options: [], context: nil)
}


override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

    if let someView: UIView = object as! UIView? {

        if (someView == self.searchController.searchResultsController?.view &&
            (keyPath == "hidden") &&
            (searchController.searchResultsController?.view.isHidden)! &&
            searchController.searchBar.isFirstResponder) {

            searchController.searchResultsController?.view.isHidden = false
        }

    }
}


func willPresentSearchController(_ searchController: UISearchController) {
    searchController.searchResultsController?.view.isHidden = false
}


func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    if (searchText.characters.count == 0) {
        searchController.searchResultsController?.view.isHidden = false
    }
}


func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
    searchController.searchResultsController?.view.isHidden = true
}