Панель поиска iOS 11, прыгающая в начало экрана

У меня есть UITableView, в котором я устанавливаю его заголовок как панель поиска.

tableView.tableHeaderView = searchController.searchBar

Все работает в соответствии с планом, пока вы не нажмете его, и он, кажется, отрывается от таблицыView и переходит в верхнюю часть экрана. Таблицы таблицы остаются на месте. По какой-либо причине это произойдет в iOS 11, а не в iOS 10?

Ответ 1

Рекомендуется применять новый способ отображения панели поиска/поиска на iOS 11. Вот что я сделал:

    if #available(iOS 11.0, *) {
        navigationItem.searchController = searchController
    } else {
        tableView.tableHeaderView = searchController.searchBar
    }

Ответ 2

Мой первый пост на SO, я надеюсь, что я сделаю это правильно.

У меня была такая же проблема и я действительно боролся с поиском решения. Но теперь мне удалось исправить это путем подкласса UISearchController.

Этот подкласс имеет два свойства:

var customDelegate : CustomSearchControllerDelegate!
var searchBarWithCustomSize : UISearchBar!

Итак, вместо использования searchBar из UISearchController теперь я могу использовать новый поиск свойстваBarWithCustomSize из моего пользовательского searchController, например:

tableView.tableHeaderView = customSearchController.searchBarWithCustomSize

Это приводит к тому, что поисковая панель ведет себя правильно, когда активна. У вас также больше свободы с этим поискомBarWithCustomSize, например, вы можете изменить его фрейм, если это необходимо, и так далее.

В моей реализации мне нужно, чтобы делегат узнал, когда текстовое поле поиска было изменено, но я предполагаю, что использование делегата зависит от вашей ситуации.

Ответ 3

У меня была одна и та же проблема - странное скачкообразное поведение UISearchBar на iOS11, где на iOS10 все в порядке.

Что касается совета Саймона Ванга выше, проблема в том, что я не определяю свой UISearchBar внутри UIViewController, я вместо этого внутри другого UITableViewCell - поэтому у меня нет доступа к navigationItem и не может отображать мою панель поиска таким образом.

В любом случае, после долгих проб и ошибок, единственный способ получить работу - это очистить UISearchController и связанных делегатов.

Вместо этого я определяю UISearchBar внутри Interface Builder и, при необходимости, определяю его ограничения компоновки. Затем я делаю свой родительский класс совместимым с UISearchBarDelegate и do searchBar.delegate = self

Затем я добавляю кучу методов делегатов, чтобы уловить изменения содержимого в строке поиска и соответственно обновить результаты моей таблицы:

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {  
   filterContentForSearchText(self.searchBar.text!)
}

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
   filterContentForSearchText(self.searchBar.text!)
   self.searchBar.resignFirstResponder()
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
   filterContentForSearchText(self.searchBar.text!)
}

И жизнь снова хороша. Надеюсь, это поможет!

Ответ 4

Попробуйте следующее:

if (@available(iOS 11, *)){
    [searchVC.searchBar addObserver:self forKeyPath:@"frame" options: NSKeyValueObservingOptionNew context:nil];
}else{
    [view addSubview:searchVC.searchBar];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    CGRect rect = [change[@"new"] CGRectValue];
    if (rect.origin.y == 14) {
        CGRect temp = rect;
        temp.origin.y = 20;
        [self.searchVC.searchBar setValue:@(temp) forKey:@"frame"];
    }else if (rect.size.height == 56){
        CGRect temp = rect;
        temp.size.height = 50;
        [self.searchVC.searchBar setValue:@(temp) forKey:@"frame"];
    }
}

Ответ 5

Попробуйте это.

if #available(iOS 11.0, *) {
    searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true
}