Swift 5 и iOS 13 UISearchController неправильно представляют и отклоняют поведение

Пока я обновлял свой проект до iOS 13, я столкнулся с необычной проблемой. У меня есть логика для отображения и обработки некоторых UISearchController действий (код ниже), все части отлично работали в iOS 11 и 12.

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

Но в iOS 13 у меня было 2 проблемы:

Код, который вызывается из действия кнопки

func showSearch() {
        let searchResultsController = LUSearchResultsViewController()...
        let searchController = UISearchController(searchResultsController: searchResultsController)
        searchController.delegate = self
        searchController.searchResultsUpdater = searchResultsController
        navigationItem.searchController = searchController
        definesPresentationContext = true
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            searchController.isActive = true
        }
}

Только одно решение помогает мне показать контроллер поиска без каких-либо отличий от предыдущих версий iOS.

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            searchController.isActive = true
}

Код, который работает на iOS 13, на iOS 11 и 12 код работает без asyncAfter

Код, который помогает мне скрыть UISearchController и установить начальное состояние панели навигации в iOS 11 и 12, а не в 13. После нажатия отмены на SearchBar UISearchController начинает вызывать методы делегирования.

  //MARK: UISearchControllerDelegate


    public func willDismissSearchController(_ searchController: UISearchController) {
         self.navigationItem.searchController = nil
    }

НО

После установки navigationItem.searchController = nil didPresentSearchController вызовы дважды и не только UISearchController отклонены, но и вся UIViewController иерархия права на UIWindow. Или, если я добавлю здесь asyncAfter, я получу нормальное отклонение с расширенной высотой навигационной панели, которая мне не нужна.

ТАК

  1. Я думаю, что asyncAfter в гвоздь, как бы вы решили эту проблему?
  2. Как правильно закрыть UISearchController?

person Wart Deider    schedule 24.09.2019    source источник
comment
UISearchController в iOS13, к сожалению, имеет несколько проблем в отношении его поведения в более ранних версиях, еще один пример - характеристики отображения SearchResultsController - мне не ясно, являются ли это ошибками или ожидаемым поведением.   -  person Nostradamus    schedule 27.09.2019


Ответы (2)


Эта проблема возникает на iOS 13.

Добавить searchController.extendedLayoutIncludesOpaqueBars = true

а также

`
extension SearchViewController:UISearchControllerDelegate{
    func willPresentSearchController(_ searchController: UISearchController) {
        if #available(iOS 13, *){
            self.navigationController?.navigationBar.isTranslucent = true
        }
    }
    func willDismissSearchController(_ searchController: UISearchController) {
        if #available(iOS 13, *){
            self.navigationController?.navigationBar.isTranslucent = false
        }
    }
}
`
person Anand Yadav    schedule 14.12.2019

Я могу помочь вам с первой частью.

Вместо выполнения асинхронной части вы можете использовать это:

searchController.searchBar.layoutIfNeeded()        
searchController.isActive = true

SearchController в данный момент не готов, и ему необходимо сначала выполнить макет, прежде чем он станет активным.

Размещая searchBar, мы вызываем это, и он срабатывает только в том случае, если есть что-то для макета.

person deejfit    schedule 26.09.2019
comment
deejfit спасибо за ответ, я пытался использовать решение с разметкой searchBar, но только asyncAfter работает нормально ( - person Wart Deider; 02.10.2019