推送/弹出期间类似消息的更高/标准导航栏

Posted

技术标签:

【中文标题】推送/弹出期间类似消息的更高/标准导航栏【英文标题】:Messages-like taller / standard navigation bar during push / pop 【发布时间】:2017-03-20 18:23:40 【问题描述】:

当您推送/弹出对话时,ios 10 消息应用的导航栏会增加/减少高度(平滑过渡)。

通常我使用sizeThatFits: 制作一个更高的自定义导航栏,但它会在导航控制器中视图控制器的推送和弹出中持续存在。

如何才能为某些跨导航序列的视图控制器(如消息应用程序)提供更高的导航栏? 谢谢!

【问题讨论】:

您找到解决方案了吗?我构建了一个UINavigationBar 扩展来设置height 值并使用该值来计算sizeThatFits 框架。现在我可以使用这个扩展来更新viewWillAppear 上的height,方法是在动画循环中设置navigationBar 高度并调用navigationBar.sizeToFit()。推的时候效果很好,不幸的是弹回来的时候效果不是很好。尝试在 viewWillDissapearviewWillAppear 上以相同方式重置之前的控制器的框架。 有进展吗,伙计们? @user370773 您可以查看我编辑的答案。我改变了为导航栏高度设置动画的方式。它适用于滑动和弹出按钮。 【参考方案1】:

非常有趣的问题。我花了一些时间在 Messages 应用中实现了类似的功能,这就是我所做的。

最后,我使用这个技巧在 push/pop 期间为 navigationBar 高度设置动画,并通过滑动手势弹出。

UIView.beginAnimations(nil, context: nil)
self.frame = navFrame
UIView.commitAnimations()

下面你可以看到我的实现:

extension UINavigationBar 
    func applyHeight(_ height: CGFloat, animated: Bool = true) 
        var navFrame = self.frame
        navFrame.size.height = height
        if animated 
            UIView.beginAnimations(nil, context: nil)
            self.frame = navFrame
            UIView.commitAnimations()
         else 
            self.frame = navFrame
        
    


class ViewControllerA: UIViewController 

    override func loadView() 
        super.loadView()
        title = "A"
        view.backgroundColor = .blue
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "NEXT", style: .plain, target: self, action: #selector(self.showController))
        navigationController?.navigationBar.isTranslucent = false
    

    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
    

    func showController() 
        navigationController?.pushViewController(ViewControllerB(), animated: true)
    


class ViewControllerB: UIViewController 

    override func loadView() 
        super.loadView()
        title = "B"
        view.backgroundColor = .red
    

    override func viewWillAppear(_ animated: Bool) 
        navigationController?.navigationBar.applyHeight(100)
        super.viewWillAppear(animated)
    

    override func willMove(toParentViewController parent: UIViewController?) 
        if parent == nil  // here you know that back button was tapped
            navigationController?.navigationBar.applyHeight(44)
        
        super.willMove(toParentViewController: parent)
    

需要改进的地方

标题跳到顶部

滑动弹出时可以看到跳转标题,但我个人认为这是一个小问题:)

希望它对您有所帮助,也许有人可以改进此实现。当然,我仍然会尝试弄清楚如何使它变得更好:) 这是github repository。请使用navigation_bar_height 分支。

【讨论】:

感谢您的回答!这看起来是一个很好的方法!唯一的问题是titleLabelbackButtonTitleLabel 在转换开始后立即跳到顶部。我想你也需要对它们应用一些偏移量。 是的,你是对的,标题偏移也是一个问题。我也会尝试解决这个问题。如果我的解决方案中有新内容,我会更新我的答案。 :) 当我自定义导航栏的高度时,我曾经覆盖导航栏的layoutSubviews。只需将所有子视图上移即可。 这个答案似乎不再适用于 iOS 11+【参考方案2】:

我认为现在你可以用这个来实现类似的东西,只需将大标题设置为 always:

【讨论】:

以上是关于推送/弹出期间类似消息的更高/标准导航栏的主要内容,如果未能解决你的问题,请参考以下文章

在动画推送和弹出时,导航项中带有搜索栏的连续视图控制器会导致视图模糊[重复]

导航栏按钮项目“撰写”在转场期间向右移动

使用标签栏控制器实现导航栏项目的更简单方法?

导航栏在动画期间不反映新的文本属性到前一个视图控制器

导航到特定视图时导航栏消失

多次推送和弹出动画 NO 后导航栏的奇怪行为。 IOS 7