【问题标题】:UISearchController - not playing well with child view controllersUISearchController - 不能很好地与子视图控制器配合使用
【发布时间】:2016-09-06 19:58:23
【问题描述】:

我有一个问题,我的当前配置是:

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 会一直显示在状态栏下方,如下所示:

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

有人对此有解决方案吗?


编辑 1:

进一步证明父 VC 中的某些东西弄乱了偏移量,UISearchBar 的实际 superView 在呈现时偏移了 -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
        }
    }
}

【问题讨论】:

  • 你有没有检查过VC的孩子是否有任何奇怪的约束?
  • 我不确定你的意思。 UISearchController 与子 VC 上的自动布局约束是分开的。唯一会受到影响的是 UISearchBar(在演示模式期间注入 UISearchController 时位于容器中)。 UISearchBar 已将掩码约束设置适当地转换为不使用指定的基于约束的布局。
  • 在大多数情况下,这绝对是在链上传达一些东西,无论是传达上下文偏移量,我都知道。
  • @TheCodingArt 你有没有设法解决这个问题?
  • @jbouaziz 除了我用来手动纠正我看到的行为的小技巧之外,没有具体的答案。我将在下面附上一个答案,也许至少可以提供帮助。

标签: ios swift layout uisearchbar uisearchcontroller


【解决方案1】:

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

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 子类中的一个被覆盖的方法。

【讨论】:

    【解决方案2】:

    供将来参考:通常这种怪异的关键是由谁来定义演示上下文。

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

    当基于上下文的展示发生时,UIKit 从展示的视图控制器开始,沿着视图控制器层次结构向上移动。如果它找到了一个该属性的值为真的视图控制器,它会要求该视图控制器呈现新的视图控制器。如果没有视图控制器定义演示上下文,UIKit 会要求窗口的根视图控制器来处理演示。

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

    【讨论】:

    • 如果您引用上面的代码,则该确切值已被操纵得太低而没有成功。我适当地设置了那个特定的标志,并且确实(在制作它时)操纵它以匹配我没有成功的预期。因此,除非您有适合这种情况的工作代码示例,否则这个答案没有任何意义,并且除了发布文档之外对问题没有任何贡献。
    • 我的感觉是你误解了定义PresentationContext的用法,因为你在willPresent上禁用它并在didPresent上重新启用,恕我直言,这个标志告诉父/子VC层次结构中的哪个视图控制器负责呈现 searchVC,因此应用它的约束以将视图保持在适当的位置,因此在搜索栏的呈现器上将其设置为 true。以我自己的经验,当您必须调整偏移量、框架等...以将其固定到位时,通常会产生难闻的气味,这意味着某些东西在概念上是错误的。希望这会有所帮助。
    • 我没有误解用法,但是还可以。在测试这个场景时,这里有一个理由这样做。无论如何,这并没有提供解决方案,而只是一个固执己见的评论。
    猜你喜欢
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多