UISearchController SearchBar 在旋转期间处于活动状态时未对齐

UISearchController SearchBar misaligns while active during rotation

我已经为 UISearchController 的搜索栏苦苦挣扎了一段时间。我需要在 table 视图上实现搜索功能,但与传统方法不同的是,我没有将搜索栏放在 table header 视图上。相反,我创建了一个 UIView 并将搜索栏添加为它的子视图。 UIView 作为搜索栏的容器,其约束已在具有自动布局的故事板上正确设置。

这是我的代码。请注意,我以编程方式执行此操作,因为 UISearchDisplayController 和 UISearchBar 从 iOS 8 开始已被弃用,取而代之的是 UISearchController,并且尚未出现在 UIKit 中。

searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.autoresizingMask = .FlexibleRightMargin
searchController.searchBar.delegate = self
definesPresentationContext = true
self.searchContainerView.addSubview(searchController.searchBar)

但是,我确实注意到搜索栏在旋转过程中出现了一种奇怪的行为。当它在纵向上处于活动状态时,我将模拟器旋转到横向,然后按取消,搜索栏返回到纵向宽度。

反之亦然。

对于解决此问题的正确方向的任何想法或一些提示,我将不胜感激,因为我至少已经这样做了好几天了。非常感谢

所以经过这么多天的努力:

人像转风景

  1. 使SearchBar/SearchController在纵向
  2. 中处于活动状态
  3. 横向旋转
  4. 按取消,SearchBar 将返回纵向宽度

风景到肖像

  1. 使SearchBar/SearchController在横向
  2. 中处于活动状态
  3. 旋转为纵向
  4. 按取消,SearchBar 将返回横向宽度

我终于自己解决了。似乎当用户在 SearchBar 上按下取消时,ViewController 将调用 viewDidLayoutSubviews 因此我尝试通过在 viewDidLayoutSubviews:

中调用此函数来重置宽度
func setupSearchBarSize(){
     self.searchController.searchBar.frame.size.width = self.view.frame.size.width
}

但这并没有我想象的那么好。所以这就是我认为会发生的事情。当用户激活 SearchController/SearchBar 时,SearchController 在调整自身大小之前保存当前帧。然后,当用户按下“取消”或将其关闭时,它将使用保存的帧并调整为该帧大小。

因此,为了在我按下取消时强制重新对齐其宽度,我必须在我的 VC 中实现 UISearchControllerDelegate 并检测 SearchController 何时被关闭,然后再次调用 setupSearchBarSize()

解决本题的相关代码如下:

class HomeMainViewController : UIViewController, UISearchControllerDelegate, UISearchResultsUpdating, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
    @IBOutlet weak var searchContainerView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()

        searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        searchController.searchBar.autoresizingMask = .FlexibleRightMargin
        searchController.searchBar.delegate = self
        searchController.delegate = self
        definesPresentationContext = true
        self.searchContainerView.addSubview(searchController.searchBar)
        setupSearchBarSize()
}

func setupSearchBarSize(){
        self.searchController.searchBar.frame.size.width = self.view.frame.size.width
}

func didDismissSearchController(searchController: UISearchController) {
        setupSearchBarSize()
}

override func viewDidLayoutSubviews() {
        setupSearchBarSize()
 }
}

这是更简单的解决方案:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)

        coordinator.animate(alongsideTransition: { (context) in
            self.searchController.searchBar.frame.size.width = self.view.frame.size.width
        }, completion: nil)
    }