在SearchBar点击显示UISearchController的SearchResultsController
我正在使用UISearchController而不是UISearchDisplayController,我想在SearchBar上显示SearchResultController马上点击。 现在它显示像这样(当我点击search栏):
当结果为空时, UISearchController
的viewController
仍然是隐藏的。 这就是为什么我们不得不绕过使用UISearchControllerDelegate
的willPresentSearchController:
初始化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 } }