While i was updating my project to iOS 13 i faced with unusual issue. I have logic for showing and handling some UISearchController
actions (code below), all parts were working perfectly in iOS 11 & 12.
My task was to add search button at navigation bar to show UISearchController
after button action.
But in iOS 13, i got 2 issues:
Code that invokes from button action
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
}
}
Only one solution helps me to show search controller without any diffs from previous iOS versions.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
searchController.isActive = true
}
Code that works on iOS 13, on iOS 11 and 12 code works without asyncAfter
Code that helps me to hide UISearchController
and set navigation bar initial state in iOS 11 and 12, and not in 13 . After tapping cancel on SearchBar, UISearchController
begins to call delegate methods.
//MARK: UISearchControllerDelegate
public func willDismissSearchController(_ searchController: UISearchController) {
self.navigationItem.searchController = nil
}
BUT
After setting navigationItem.searchController = nil
didPresentSearchController
calls twice and not only UISearchController
dismissed, but whole UIViewController
hierarchy right to UIWindow
. Or if i add asyncAfter
here i get normal dismiss with expanded nav bar height, that i don't need.
SO
This issue is happening on iOS 13
Add searchController.extendedLayoutIncludesOpaqueBars = true
as well as
`
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
}
}
}
`
I can help you with the first part.
Instead of doing the async part you can use this:
searchController.searchBar.layoutIfNeeded()
searchController.isActive = true
The SearchController isn't ready at that particular moment and it needs to layout first before it can become active.
By layout-ing the searchBar we force this and it will only trigger if there's something to layout.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.