如何在iOS 11的navigationBar中模仿UITableViewController大标题的显示 [英] How to mimic `UITableViewController` showing of the large titles in `navigationBar` on iOS 11

查看:46
本文介绍了如何在iOS 11的navigationBar中模仿UITableViewController大标题的显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  navigationController?.navigationBar.prefersLargeTitles = true 

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

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

尽管这些约束像我期望的那样显示了 tableView ,但现在导航栏始终使用大标题.我想模仿 UITableViewController 的行为,以便当 tableView 滚动到顶部时,会显示较大的标题,否则标题会折叠为普通标题.

如何解决这个问题?

解决方案

我注意到 prefersLargeTitle 行为的另一个方面,在某些情况下,它甚至可以提供更简单,更优雅的解决方案.就我而言, viewController 不仅包含 tableView (否则,我将只使用 UITableViewController ,而我将获得标准的 prefersLargeTitle 行为),还有其他一些视图.现在我注意到,如果将 tableView 添加为 viewController.view 的第一个子视图,则该表将控制大标题功能:

 //这将起作用fileprivate func setupInitialHierarchy(){self.view.addSubview(tableView)self.view.addSubview(logoffButton)} 

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

 //由于某种原因现在tableView将无法控制大标题fileprivate func setupInitialHierarchy(){self.view.addSubview(logoffButton)self.view.addSubview(tableView)} 

所以看来,如果 tableView viewController view 的第一个子视图,我们将获得标准的大标题行为./p>

替代解决方案

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

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

  func scrollViewDidScroll(_ scrollView:UIScrollView){如果scrollView.contentOffset.y< = 0 {self.navigationItem.largeTitleDisplayMode =.始终} 别的 {self.navigationItem.largeTitleDisplayMode = .never}self.navigationController?.navigationBar.setNeedsLayout()self.view.setNeedsLayout()UIView.animate(withDuration:0.25,动画:{self.navigationController?.navigationBar.layoutIfNeeded()self.view.layoutIfNeeded()})} 

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

I'm trying to use prefersLargeTitles from iOS 11 in my application. It works as expected in subclasses of UITableViewController:

navigationController?.navigationBar.prefersLargeTitles = true

However, in one case I needed to subclass UIViewController and add a table view myself. In this situation I needed to constraint the table to the view myself:

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

While these constraints present the tableView as I would expect, now the navigation bar always uses large title. I would like to mimic the behavior of the UITableViewController, so that when the tableView is scrolled to top, the large title is presented, otherwise the title collapses into the normal one.

How to solve this?

解决方案

I noticed another aspect of prefersLargeTitle behavior that in some cases might provide even a simpler and more elegant solution. In my case, the viewController contained not only the tableView (otherwise I would simply use UITableViewController and I would get standard prefersLargeTitle behavior out-of-the-box), but also some other views. Now I noticed, that if you add the tableView as a first subview of the viewController.view, the table will control the large title feature:

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

Before I was creating the view hierarchy as follows:

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

So it seems that if the tableView is the first subview of the viewControllers view, we get the standard large titles behavior.

Alternative solution

However, if this is not possible, I have been able to simulate the standard behavior programmatically this way:

Implementing the delegate method for the tableView that reacts to scrolling, and then running the code that uses current contentOffset to either show, or hide the large title (UITableView inherits from UIScrollView, so the scrollView parameter refers in this case to the 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()
    })
}

Just remember that scrollViewDidScroll gets called repeatedly, so some guard there might be desirable.

这篇关于如何在iOS 11的navigationBar中模仿UITableViewController大标题的显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆