如何正确地动画推送带有透明导航栏和工具栏的视图控制器?

Posted

技术标签:

【中文标题】如何正确地动画推送带有透明导航栏和工具栏的视图控制器?【英文标题】:How do I properly animate pushing a view controller with a transparent navigation bar and toolbar? 【发布时间】:2019-09-11 19:47:52 【问题描述】:

在我的应用程序的导航控制器中,我想推送一个带有清晰导航栏和工具栏的视图控制器。当第一个视图控制器再次出现时,我希望导航栏和工具栏再次具有它们的默认外观。

我在模拟器设置中打开了慢速动画,以便您查看它的外观:

导航栏上方和主页指示器下方的区域在过渡期间看起来不太正确,因为那里什么都没有,而实际的导航栏和工具栏会淡出。

此外,当弹出控制器时,工具栏会立即出现。当使用向后滑动手势以交互方式将其关闭时,这看起来尤其糟糕。

我或许可以使用 ios 13 中的新 UIBarAppearance 类让它看起来不错,但我想继续支持旧版本的 iOS。

这是我到目前为止的代码。这些方法在细节视图控制器中。此外,我不想真正将背景颜色设置为白色,而是获得默认的模糊外观,即使在暗模式下也是如此,但不确定将其设置回什么。

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

    func doThings() 
        navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
        navigationController?.navigationBar.shadowImage = UIImage()
        navigationController?.navigationBar.backgroundColor = .clear
        navigationController?.navigationBar.barTintColor = .clear

        navigationController?.toolbar.setBackgroundImage(UIImage(), forToolbarPosition: .bottom, barMetrics: .default)
        navigationController?.toolbar.setShadowImage(UIImage(), forToolbarPosition: .bottom)
        navigationController?.toolbar.backgroundColor = .clear
        navigationController?.toolbar.barTintColor = .clear
    

    guard self.navigationController?.topViewController === self else  return 
    let animationsWereQueuedSuccessfully = self.transitionCoordinator?.animate(alongsideTransition:  [weak self] context in
        guard self != nil else  return 
        doThings()
    , completion: nil)

    if animationsWereQueuedSuccessfully != true 
        doThings()
    


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

    func doThings() 
        navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
        navigationController?.navigationBar.shadowImage = nil
        navigationController?.navigationBar.backgroundColor = .white
        navigationController?.navigationBar.barTintColor = .white

        navigationController?.toolbar.setBackgroundImage(nil, forToolbarPosition: .bottom, barMetrics: .default)
        navigationController?.toolbar.setShadowImage(nil, forToolbarPosition: .bottom)
        navigationController?.toolbar.backgroundColor = .white
        navigationController?.toolbar.barTintColor = .white
    

    let animationsWereQueuedSuccessfully = self.transitionCoordinator?.animate(alongsideTransition:  [weak self] context in
        guard self != nil else  return 
            doThings()
    , completion: nil)

    if animationsWereQueuedSuccessfully != true 
        doThings()
    

【问题讨论】:

【参考方案1】:

我建议进行自定义转换。听起来您需要比默认推送更多的功能。这是一篇中篇文章。

https://medium.com/chili-labs/custom-navigation-transitions-f791ff0a46aa

【讨论】:

以上是关于如何正确地动画推送带有透明导航栏和工具栏的视图控制器?的主要内容,如果未能解决你的问题,请参考以下文章

推送视图控制器中的半透明导航栏覆盖?

带有搜索图标的 UINavigationBar - 单击时推送模态搜索视图

隐藏导航栏,取决于视图控制器的显示方式

如何通过推送通知显示带有 TabBarController 导航的视图控制器

iOS 7 UITableView 使用透明的导航栏和工具栏

如何使用情节提要正确地转到嵌入式选项卡栏和导航控制器?