如何转换/动画UINavigationBar的颜色? [英] How do I transition/animate color of UINavigationBar?

查看:136
本文介绍了如何转换/动画UINavigationBar的颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找如何过渡/动画 barTintColor UINavigationBar 一段时间了,我只看到不同的答案。有些使用 UIView.animateWithDuration ,有些使用 CATransition ,但最有趣的是,例如




  • 第一个的推送过渡到第二个看起来很完美。所有元素都完美转换,可能除了StatusBar,它立即变为白色。我宁愿知道如何转换它,但我现在会接受它。

  • Second 到pop的转换首先是完全错误的。它保持第二的颜色,直到转换完成。

  • 第二次拖动转换第一次在完全拖动时看起来没问题。同样,一旦我开始拖动,StatusBar立即变黑,但我不知道是否可以修复。

  • 第二次拖动转换第一个但取消了中期拖动并返回第二个完全搞砸了。它看起来很好,直到第二完全恢复控制,然后它突然变为 First -colors。这不应该发生。



我对我的 RootViewController 进行了一些更改让它好一点。我完全删除了 viewWillAppear:,并将其更改为:

  class RootViewController:UIViewController {

覆盖func willMove(toParentViewController parent:UIViewController?){
如果让last = self.navigationController?.viewControllers.last为? RootViewController {
if last == self&& self.navigationController!.viewControllers.count> 1 {
如果让parent = self.navigationController!.viewControllers [self.navigationController!.viewControllers.count - 2]为? RootViewController {
parent.setNavigationColors()
}
}
}
}
覆盖func viewWillDisappear(_ animated:Bool){
if让parent = navigationController?.viewControllers.last为? RootViewController {
parent.animateNavigationColors()
}
}
覆盖func viewDidAppear(_ animated:Bool){
self.setNavigationColors()
}

func animateNavigationColors(){
transitionCoordinator?.animate(withsideTransition:{$ weak self](context)in
self?.setNavigationColors()
},完成: nil)
}
func setNavigationColors(){
//在子类中覆盖
}
}

使用此更新的代码,我得到:



一些观察结果:




  • 第一过渡到第二个是相同的

  • 第二的首次转换现在正确动画,但从后面除外-arrow,back-text(和statusBar,但是是啊..)。这些立即变为黑色。在第一个gif中,您可以看到后箭头和后退文本也已转换。

  • 第二次到第一个也有这个问题,后面的箭头和后面的文字在启动时会突然变黑。 barTint是固定的,因此在取消拖动时它没有得到错误的颜色。



我做错了什么?我该怎么做呢?



我想要的是顺利过渡所有元素。后退按钮,后退文本,标题,barTint和statusBar的色调。这不可能吗?

解决方案


10个iOS中的

它运行不完美:(



将导航控制器子类化为使用可见视图控制器的statusbarstyle:

 类MyNavigationController:UINavigationController的{
改写VAR preferredStatusBarStyle:UIStatusBarStyle {
返回visibleViewController .preferredStatusBarStyle
}
}

覆盖Root控制器中的preferredStatusBarStyle并添加函数以在 pop动画之前设置样式

  private var _preferredStyle = UIStatusBarStyle.default; 
覆盖var preferredStatusBarStyle:UIStatusBarStyle {
get {
return _preferredStyle
}
set {
_preferredStyle = NEWVALUE
self.setNeedsStatusBarAppearanceUpdate()
}

}


FUNC animateNavigationColors(){
self.setBeforePopNavigationColors ()
transitionCoordinator?.animate(withsideTransition:{$ weak self](context)in
self?.setNavigationColors()
},completion:nil)
}

func setBeforePopNavigationColors(){
//在子类中覆盖
}

在第一个控制器中:

 覆盖func setBeforePopNavigationColors(){
navigationController?.navigationBar.tintColor = UIColor。白色
navigationController .navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.white]
self.preferredStatusBarStyle = UIStatusBarStyle.lightContent
}

改写FUNC setNavigationColors() {
navigationController?.navigationBar.barTintColor = UIColor.wh ?ITE
navigationController .navigationBar.tintColor = UIColor.black
navigationController .navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.black]?
navigationController .navigationBar.barStyle = UIBarStyle.default
self.preferredStatusBarStyle = UIStatusBarStyle.default
}

第二名:

 覆盖func setNavigationColors(){
navigationController?.navigationBar.barTintColor = UIColor.black
navigationController?.navigationBar。 tintColor = UIColor.white
navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.white]
navigationController?.navigationBar.barStyle = UIBarStyle.black
self.preferredStatusBarStyle = UIStatusBarStyle.lightContent
}

示例项目: https://github.com/josshad/TestNavBarTransition


I have been searching for how to transition/animate the barTintColor of a UINavigationBar for a while now, and I only see different answers. Some use UIView.animateWithDuration, some use CATransition, but the most interesting ones, like this one use animate(alongsideTransition animation.., which I like the sound of, but I can't get it working properly. Am I doing something wrong?

Many specify that I can simply use the transitionCoordinator in viewWillAppear:. I have set up a fresh super tiny project like this:

class RootViewController:UIViewController{ //Only subclassed
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        transitionCoordinator?.animate(alongsideTransition: { [weak self](context) in
            self?.setNavigationColors()
            }, completion: nil)
    }
    func setNavigationColors(){
        //Override in subclasses
    }
}

class FirstViewController: RootViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "First"
    }
    override func setNavigationColors(){
        navigationController?.navigationBar.barTintColor = UIColor.white
        navigationController?.navigationBar.tintColor = UIColor.black
        navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.black]
        navigationController?.navigationBar.barStyle = UIBarStyle.default
    }
}
class SecondViewController: RootViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "Second"
    }
    override func setNavigationColors(){
        navigationController?.navigationBar.barTintColor = UIColor.black
        navigationController?.navigationBar.tintColor = UIColor.white
        navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
        navigationController?.navigationBar.barStyle = UIBarStyle.black
    }
}

With this code, this happens:

  • The push-transition from First to Second looks perfect. All elements transition perfectly, maybe except the StatusBar, which instantly changes to white. I'd rather know how to transition it, but I'll accept it for now.
  • The pop-transition from Second to First is completely wrong. It keeps the colors from Second until the transition is completely done.
  • The drag-transition from Second to First looks alright, when dragging all the way over. Again, the StatusBar instantly becomes black as soon as I start dragging, but I don't know if that's possible to fix.
  • The drag-transition from Second to First but cancelled mid-drag and returning to Second is completely screwed up. It looks fine until Second is completely back in control, and then it suddenly changes itself to First-colors. This should not happen.

I made a few changes to my RootViewController to make it a little better. I removed viewWillAppear: completely, and changed it with this:

class RootViewController:UIViewController{

    override func willMove(toParentViewController parent: UIViewController?) {
        if let last = self.navigationController?.viewControllers.last as? RootViewController{
            if last == self && self.navigationController!.viewControllers.count > 1{
                if let parent = self.navigationController!.viewControllers[self.navigationController!.viewControllers.count - 2] as? RootViewController{
                    parent.setNavigationColors()
                }
            }
        }
    }
    override func viewWillDisappear(_ animated: Bool) {
        if let parent = navigationController?.viewControllers.last as? RootViewController{
            parent.animateNavigationColors()
        }
    }
    override func viewDidAppear(_ animated: Bool) {
        self.setNavigationColors()
    }

    func animateNavigationColors(){
        transitionCoordinator?.animate(alongsideTransition: { [weak self](context) in
            self?.setNavigationColors()
            }, completion: nil)
    }
    func setNavigationColors(){
        //Override in subclasses
    }
}

With this updated code, I get this:

A few observations:

  • The transition from First to Second is the same
  • The pop-transition from Second to First is now animating correctly, except from the back-arrow, the back-text (and the statusBar, but yeah..). These are instantly changed to black. In the first gif, you could see that the back-arrow and the back-text also transitioned.
  • The drag-transition from Second to First also has this problem, the back-arrow and back-text are suddenly instantly black when starting. The barTint is fixed so that it doesn't get the wrong color when cancelling the drag.

What am I doing wrong? How am I supposed to do this?

What I want is to transition all elements smoothly. The tint of the back-button, the back-text, the title, the barTint, and the statusBar. Is this not possible?

解决方案

in 10 iOS it works imperfectly :(

Subclass your navigation controller to use statusbarstyle of visible view controller:

class MyNavigationController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return visibleViewController!.preferredStatusBarStyle
    }
}

Override preferredStatusBarStyle in Root controller and add function to set styles before pop animation:

private var _preferredStyle = UIStatusBarStyle.default;
override var preferredStatusBarStyle: UIStatusBarStyle {
    get {
        return _preferredStyle
    }
    set {
        _preferredStyle = newValue
        self.setNeedsStatusBarAppearanceUpdate()
    }

}


func animateNavigationColors(){
        self.setBeforePopNavigationColors()
        transitionCoordinator?.animate(alongsideTransition: { [weak self](context) in
            self?.setNavigationColors()
            }, completion: nil)
    }

func setBeforePopNavigationColors() {
    //Override in subclasses
}

In first controller:

override func setBeforePopNavigationColors() {
    navigationController?.navigationBar.tintColor = UIColor.white
    navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    self.preferredStatusBarStyle = UIStatusBarStyle.lightContent
}

override func setNavigationColors(){
    navigationController?.navigationBar.barTintColor = UIColor.white
    navigationController?.navigationBar.tintColor = UIColor.black
    navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.black]
    navigationController?.navigationBar.barStyle = UIBarStyle.default
    self.preferredStatusBarStyle = UIStatusBarStyle.default
}

In second:

  override func setNavigationColors(){
        navigationController?.navigationBar.barTintColor = UIColor.black
        navigationController?.navigationBar.tintColor = UIColor.white
        navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
        navigationController?.navigationBar.barStyle = UIBarStyle.black
        self.preferredStatusBarStyle = UIStatusBarStyle.lightContent
    }

Example project: https://github.com/josshad/TestNavBarTransition

这篇关于如何转换/动画UINavigationBar的颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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