简体   繁体   English

Swift 5 & iOS 13 UISearchController 错误的呈现和关闭行为

[英]Swift 5 & iOS 13 UISearchController wrong presenting and dismissing behaviour

While i was updating my project to iOS 13 i faced with unusual issue.当我将我的项目更新到 iOS 13 时,我遇到了不寻常的问题。 I have logic for showing and handling some UISearchController actions (code below), all parts were working perfectly in iOS 11 & 12.我有显示和处理一些UISearchController操作的逻辑(下面的代码),所有部分在 iOS 11 和 12 中都运行良好。

My task was to add search button at navigation bar to show UISearchController after button action.我的任务是在导航栏添加搜索按钮以在按钮操作后显示UISearchController

But in iOS 13, i got 2 issues:但是在 iOS 13 中,我遇到了 2 个问题:

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.只有一种解决方案可以帮助我显示搜索 controller 与以前的 iOS 版本没有任何差异。

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适用于 iOS 13、iOS 11 和 12 的代码无需asyncAfter即可工作

Code that helps me to hide UISearchController and set navigation bar initial state in iOS 11 and 12, and not in 13 .帮助我隐藏UISearchController在 iOS 11 和 12 中设置导航栏初始 state 的代码,而不是在 13 中 After tapping cancel on SearchBar, UISearchController begins to call delegate methods.点击 SearchBar 上的取消后, UISearchController开始调用委托方法。

  //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 .设置navigationItem.searchController = nil didPresentSearchController调用两次后,不仅UISearchController被解雇,而且整个UIViewController层次结构都直接到UIWindow Or if i add asyncAfter here i get normal dismiss with expanded nav bar height, that i don't need.或者,如果我在这里添加asyncAfter ,我会通过扩展导航栏高度正常关闭,我不需要。

SO所以

  1. I think that asyncAfter in a dog-nail, how would you solve this problem?我认为 asyncAfter 在狗钉中,你将如何解决这个问题?
  2. How can i dismiss UISearchController correctly?如何正确关闭 UISearchController?

This issue is happening on iOS 13这个问题发生在iOS 13

Add searchController.extendedLayoutIncludesOpaqueBars = true添加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. SearchController 在那个特定时刻还没有准备好,它需要先布局才能激活。

By layout-ing the searchBar we force this and it will only trigger if there's something to layout.通过对 searchBar 进行布局,我们强制执行此操作,它只会在需要布局时触发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM