Я использую UISearchController, а не UISearchDisplayController, и я хочу сразу показать SearchResultController на SearchBar Tap. Сейчас это выглядит так (когда я нажимаю на строку поиска):
Я использую UISearchController, а не UISearchDisplayController, и я хочу сразу показать SearchResultController на SearchBar Tap. Сейчас это выглядит так (когда я нажимаю на строку поиска):
Когда результаты пусты, 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;
});
}
Асинхронная отправка необходима, поскольку в противном случае она будет переопределена внутренним поведением. Вы могли бы придумать здесь и использовать анимацию, чтобы увидеть, как выглядит таблица.
didPresentSearchController:
для удобства:- (void)didPresentSearchController:(UISearchController *)searchController
{
searchController.searchResultsController.view.hidden = NO;
}
Я обнаружил, что другие ответы мерцали из-за использования 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;
}
Ответ Криса Васселли - самый чистый способ реализовать это.
Здесь он находится в 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 пуст, а preload tableview снова исчезнет.
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
}
}