UISearchController - 与子视图控制器不兼容

时间:2016-09-06 19:58:24

标签: ios swift layout uisearchbar uisearchcontroller

我遇到的问题是我目前的配置是:

UITableViewController - > UINavigationController - >用于交换2个子视图控制器的ViewController。

每个子视图控制器都有一个与之关联的UISearchController。当UISearchBar激活时,它似乎永远不会有正确的位置。

extension MySearchViewController: UISearchControllerDelegate {

    func willPresentSearchController(searchController: UISearchController) {
        var adjustedOrigin = searchController.searchBar.frame.origin
        //FIXME: There's some odd behavior with embedded child VCs where the status bar adjustments are not taken into consideration
        adjustedOrigin.y += UIApplication.sharedApplication().statusBarFrame.height
        searchController.searchBar.frame.origin = adjustedOrigin
        definesPresentationContext = false
        navigationController?.definesPresentationContext = true
        navigationController?.extendedLayoutIncludesOpaqueBars = true
    }

    func didPresentSearchController(searchController: UISearchController) {
        definesPresentationContext = true

    }

    func didDismissSearchController(searchController: UISearchController) {
        var adjustedOrigin = searchController.searchBar.frame.origin
        //FIXME: There's some odd behavior with embedded child VCs where the status bar adjustments are not taken into consideration
        adjustedOrigin.y -= UIApplication.sharedApplication().statusBarFrame.height

        searchController.searchBar.frame.origin = adjustedOrigin
    }

}

您可以在上面看到调整原点,因为我正在尝试手动修正UISearchBar的偏移量,这是迄今为止不首选的。我试图在故事板中检查(在许多区域中)显示器,并且几乎在层次结构中的所有地方都通过代码。我似乎无法找到抵消的罪魁祸首。默认情况下,UISearchBar将一直显示在状态栏下:

search screen

这是没有我的手动调整仍然有点偏。

有人有解决方案吗?

编辑1:

进一步证明父VC中的某些内容正在弄乱偏移量,UISearchBar的实际超级视图在呈现时会偏移-20。因此,以下更正了问题:

import UIKit

class MySearchController: UISearchController {

    override func viewDidLoad() {
        super.viewDidLoad()
        edgesForExtendedLayout = .Top
        extendedLayoutIncludesOpaqueBars = true
        automaticallyAdjustsScrollViewInsets = true 

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        print(active)

        if active && searchBar.superview!.frame.origin != CGPoint.zero {
            searchBar.superview?.frame.origin = CGPoint.zero
        }
    }
}

2 个答案:

答案 0 :(得分:0)

以下是我发现可以可靠地调整状态栏偏移的唯一方法,搜索控制器错误地调整了。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    //FIXME: Unfortunate hack required to adjust for offset of -20 pulled from ????? where ?????
    guard let searchBarContainerView = searchBar.superview where (active && searchBarContainerView.frame.origin != CGPoint.zero) else {
        return
    }
    searchBarContainerView.frame.origin = CGPoint.zero
}

请注意,物理原点被-20作为状态栏的高度所抵消。修正是为了确保原点强制设置为0。

另请注意,这是UISearchController子类中的重写方法。

答案 1 :(得分:-1)

供将来参考:通常,这种奇怪的关键是谁在定义表示背景。

来自文档: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621456-definespresentationcontext

当发生基于上下文的演示时,UIKit从呈现视图控制器开始,在视图控制器层次结构中向上走。如果找到该属性值为true的视图控制器,则会要求视图控制器显示新的视图控制器。如果没有视图控制器定义表示上下文,UIKit会要求窗口的根视图控制器处理演示文稿。

所以基本上你必须确保层次结构中的右视图控制器将definePresentationContext设置为YES。如果正确放置,则不需要偏移或框架修改。在您的情况下,您的父VC可能需要定义表示上下文,并确保没有子VC将其设置为YES。