setNavigationBarHidden动画在iPhone X上无法正常工作

时间:2017-11-11 15:41:07

标签: ios animation uinavigationbar iphone-x

我的代码通过隐藏UINavigationController的导航栏进入全屏模式。进入全屏时,我想要一个平滑的动画缩放效果。我使用setNavigationBarHidden(_:animated:)。到目前为止,这一切都运行良好,即使在iOS 11上,但在iPhone X上,动画效果不佳。在隐藏时,没有动画,导航栏就消失了。在取消隐藏时,它会进行动画处理,但导航栏的显示速度比导航控制器的内容区域减少的速度慢,因此在动画期间会通过导航栏区域显示丑陋的黑色背景。

我可以在一个简单的测试应用程序中重新创建它。我有一个嵌入在UINavigationController中的UIViewController。

故事板

  • UINavigationController导航栏:Style == Black;半透明关闭
  • UIViewController:Extend Edges:所有选项OFF。

我已经尝试了我能想到的调整滚动视图插入和扩展边缘的所有组合,但它们没有任何区别。

代码

{{1}}

Result on iPhone X (slow animations)

2 个答案:

答案 0 :(得分:2)

在您的情况下,您同时使用barTintColor&带有navigationBarStyle Show动画的Hide barTintColor会覆盖Style属性隐含的值 您应该选择barTintColornavigationBarStyle 在下面的代码中,我刚刚使用了barTintColor& navigationBarStyle默认为Transulent

enter image description here

    var fullScreen = false{
      didSet{
        self.setNeedsStatusBarAppearanceUpdate()
     }
   }
    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Navigation Bar"
        navigationController?.navigationBar.barTintColor = .red
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        setFullScreen(on: fullScreen, animated: animated)
    }
    @IBAction func onToggleNavBarVisibility(_ sender: Any) {
        if let navBarHidden = 
          self.navigationController?.isNavigationBarHidden {
            // Toggle the state
            fullScreen = !navBarHidden
            setFullScreen(on: fullScreen, animated: true)
        }
    }
    private func setFullScreen(on : Bool, animated : Bool) {
        self.navigationController?.setNavigationBarHidden(on, animated: animated)
        self.setNeedsStatusBarAppearanceUpdate()
    }

修改 如果你想隐藏状态栏 - 将prefersStatusBarHidden与bool值一起使用。 &安培;使用setNeedsStatusBarAppearanceUpdate

   override var prefersStatusBarHidden: Bool {
        return fullScreen
    }

https://developer.apple.com/documentation/uikit/uinavigationbar

答案 1 :(得分:0)

这显然是一个 UIKit 错误。我已提交 FB8980917:

<块引用>

当导航栏与状态栏同时隐藏时 使用幻灯片动画,导航栏隐藏没有动画。 在相反的方向,状态栏出现淡入淡出 动画而不是指定的幻灯片动画。

要重现,请运行附带的示例项目。使用模拟器的慢 动画或记录设备的屏幕并逐步浏览帧。

我还附上了“屏幕视频.mp4”供您参考。

注 1:作为一种解决方法,我们可以求助于已弃用的 UIApplication.setStatusBarHidden(_:with:) API(参见“屏幕视频 legacy.mp4")。除了状态栏动画之外,这主要是有效的 持续时间长于导航栏动画持续时间。 但是,它需要设置 UIViewControllerBasedStatusBarAppearance=NO in Info.plist 所以它是一个 选择退出整个现代应用程序的全有或全无方法 API。

注意 2:为 preferredStatusBarUpdateAnimation 返回 .fade 不会 工作。第一,难看,因为导航栏还在滑动 淡出(并且不能配置淡出),二来的问题 导航栏缺少隐藏动画仍然存在。

注意 3:使用 UINavigationController 的 hidesBarsOnTap 属性不会 工作。问题依然存在。示例应用程序还有 hidesBarsOnTap 已启用。

示例代码:

class ViewController: UIViewController {
    var fullScreen = false

    override var prefersStatusBarHidden: Bool {
        return navigationController!.isNavigationBarHidden
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    
    override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
        return .slide
    }

    @IBAction func toggleFullscreen(_ sender: Any) {
        fullScreen = !fullScreen

        navigationController?.setNavigationBarHidden(fullScreen, animated: true)
        setNeedsStatusBarAppearanceUpdate()
    }
}

虽然 Note 1 中描述的解决方法有效,但我不能推荐它,因为自 iOS 9.0 以来 API 已被弃用。所以真的,这是@Apple 人来解决这个问题。照片等应用实现了类似的行为而没有该错误的事实表明,有一种方法可以做到这一点,尽管使用私有 API 或丑陋的黑客攻击。