【问题标题】:How to mimic `UITableViewController` showing of the large titles in `navigationBar` on iOS 11如何在 iOS 11 的“导航栏”中模仿“UITableViewController”显示大标题
【发布时间】:2017-09-12 14:19:31
【问题描述】:

我正在尝试在我的应用程序中使用来自 iOS 11 的 prefersLargeTitles。它在UITableViewController 的子类中按预期工作:

navigationController?.navigationBar.prefersLargeTitles = true

但是,在一种情况下,我需要继承 UIViewController 并自己添加一个表格视图。在这种情况下,我需要自己将表约束到视图:

tableView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: self.otherView.topAnchor).isActive = true

虽然这些约束如我预期的那样呈现tableView,但现在导航栏总是使用大标题。我想模仿UITableViewController 的行为,这样当tableView 滚动到顶部时,会显示大标题,否则标题会折叠成普通标题。

如何解决?

【问题讨论】:

    标签: swift uitableview ios11


    【解决方案1】:

    我注意到prefersLargeTitle 行为的另一个方面,在某些情况下可能会提供更简单、更优雅的解决方案。在我的例子中,viewController 不仅包含tableView(否则我会简单地使用UITableViewController,我会得到标准的prefersLargeTitle 开箱即用的行为),还包含其他一些视图。现在我注意到,如果您将tableView 添加为viewController.view 的第一个子视图,表格将控制大标题功能:

    // this will work
    fileprivate func setupInitialHierarchy() {
        self.view.addSubview(tableView)
        self.view.addSubview(logoffButton)
    }
    

    在创建视图层次结构之前,如下所示:

    // for some reason now the tableView will not control the large title
    fileprivate func setupInitialHierarchy() {
        self.view.addSubview(logoffButton)
        self.view.addSubview(tableView)
    }
    

    因此,如果tableViewviewControllers view 的第一个子视图,我们会得到标准的大标题行为。

    替代解决方案

    但是,如果这是不可能的,我已经能够以这种方式以编程方式模拟标准行为:

    实现对滚动作出反应的tableView 的委托方法,然后运行使用当前contentOffset 的代码来显示或隐藏大标题(UITableView 继承自UIScrollView,因此@ 987654337@ 参数在这种情况下指的是tableView):

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollView.contentOffset.y <= 0 {
            self.navigationItem.largeTitleDisplayMode = .always
        } else {
            self.navigationItem.largeTitleDisplayMode = .never
        }
        self.navigationController?.navigationBar.setNeedsLayout()
        self.view.setNeedsLayout()
        UIView.animate(withDuration: 0.25, animations: {
            self.navigationController?.navigationBar.layoutIfNeeded()
            self.view.layoutIfNeeded()
        })
    }
    

    请记住,scrollViewDidScroll 会被反复调用,因此可能需要一些 guard

    【讨论】:

    • 是的,你是对的。自 iOS 7 以来,当最初引入 automaticAdjustsScrollViewInsets 时,顺序很重要。因此,为了使该标志与子视图的自定义层次结构一起使用,它需要 UIScrollView(或子类作为根视图)。所以我想这里也是一样。
    猜你喜欢
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 1970-01-01
    • 2018-04-29
    • 2013-10-28
    • 1970-01-01
    相关资源
    最近更新 更多