在SearchBar点击显示UISearchController的SearchResultsController

我正在使用UISearchController而不是UISearchDisplayController,我想在SearchBar上显示SearchResultController马上点击。 现在它显示像这样(当我点击search栏):

当结果为空时, UISearchControllerviewController仍然是隐藏的。 这就是为什么我们不得不绕过使用UISearchControllerDelegatewillPresentSearchController:

初始化self.searchController使你的ViewController符合`UISearchControllerDelegate:

 self.searchController.delegate = self; 

实现willPresentSearchController:在你的ViewController中:

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

asynchronous调度是必要的,否则它将被内部行为覆盖。 你可以在这里看中,并使用animation来使桌面视图淡入。

此外,实现didPresentSearchController:为了理智:

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

我发现由于使用dispatch_async ,其他答案闪烁。 他们使用这种方式,以便在search控制器的内部行为完成后应用它们的更改,但是这会在应用内部行为之前留下几个帧,然后重写。 使用KVO允许我立即覆盖内部行为而不闪烁。

我还发现,其他答案没有保持search结果控制器可见,当用户点击ⓧbutton来清除search栏的内容,这似乎是不正确的。

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

我觉得这个方法比较好,当searchBar是空的时候要小心,然后预览tableview会再次消失。

UISearchBarDelegate

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

UISearchControllerDelegate

 func willPresentSearchController(searchController: UISearchController) { dispatch_async(dispatch_get_main_queue()) { self.searchController.searchResultsController?.view.hidden = false } }