在SearchBar Tap上显示UISearchController的SearchResultsController

Att*_*iqe 18 ios uisearchcontroller

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

tub*_*tub 23

如果结果是空的,UISearchControllerviewController仍有隐忧.这就是为什么我们必须摆弄使用UISearchControllerDelegate's'的方式willPresentSearchController:

初始化后,self.searchController使ViewController符合`UISearchControllerDelegate:

self.searchController.delegate = self;
Run Code Online (Sandbox Code Playgroud)

willPresentSearchController:在ViewController中实现:

- (void)willPresentSearchController:(UISearchController *)searchController
{
    dispatch_async(dispatch_get_main_queue(), ^{
        searchController.searchResultsController.view.hidden = NO;
    });
}
Run Code Online (Sandbox Code Playgroud)

异步调度是必要的,否则它将被内部行为覆盖.您可以在这里看上去并使用动画让表格视图淡入.

另外,实现didPresentSearchController:健全:

- (void)didPresentSearchController:(UISearchController *)searchController
{
    searchController.searchResultsController.view.hidden = NO;
}
Run Code Online (Sandbox Code Playgroud)

  • @tubtub这对于首次发布非常有用.如果我们输入内容然后完全删除输入的文本,resultsController将再次隐藏.还有办法解决这个问题吗? (2认同)

Chr*_*lli 9

我发现其他答案由于使用而闪烁dispatch_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;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

克里斯·瓦塞利(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
}
Run Code Online (Sandbox Code Playgroud)