Подтвердить что ты не робот

Показать UISearchController SearchResultsController на SearchBar Tap

Я использую UISearchController, а не UISearchDisplayController, и я хочу сразу показать SearchResultController на SearchBar Tap. Сейчас это выглядит так (когда я нажимаю на строку поиска):

x4eTZ.png

4b9b3361

Ответ 1

Когда результаты пусты, 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;
}

Ответ 2

Я обнаружил, что другие ответы мерцали из-за использования 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;
}

Ответ 3

Ответ Криса Васселли - самый чистый способ реализовать это.

Здесь он находится в 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
}

Ответ 4

Я думаю, что этот метод лучше, будьте осторожны, когда searchBar пуст, а preload 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
    }
}