Present/Dismiss UISearchController in UINavigationBar via button

While i was updating my project to iOS 13 i faced an 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 searchButtonTapped() { 

self.navigationItem.searchController = self.searchController

self.definesPresentationContext = true

self.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

  1. I think that asyncAfter in a dog-nail, how would you solve this problem?
  2. How can i dismiss UISearchController correctly?
Did you find solution for UISearchBar cancel button not to dimiss entire viewController having navigationItem.searchController assigned?

Code Block
if viewController.navigationItem.searchController != nil {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                viewController.navigationItem.searchController = nil
            }


Really I need to add 0.1 delay to make it work? Isn't it a little stupid hacky soluton.

This solution kind of works, but it's stopped working in some cases in release builds.

I have an accesoryInputView in the main controller and the search controller which appears after the long tap on the navigation bar (it's searching messages in chat like Telegram does). So, this solution works well on iOS < 15.1 and also on all debug builds.

But when it comes to release-scheme build – search bar occasionally may be dismissed with a parent view controller.

It's so weird, because now I need hacky solution over the hacky solution. I would expect some fix for this issue from Apple but right now issue only become more complicated =)

Present/Dismiss UISearchController in UINavigationBar via button
 
 
Q