如何转换/动画UINavigationBar的颜色? [英] How do I transition/animate color of 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
toSecond
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
toFirst
is completely wrong. It keeps the colors fromSecond
until the transition is completely done. - The drag-transition from
Second
toFirst
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
toFirst
but cancelled mid-drag and returning toSecond
is completely screwed up. It looks fine untilSecond
is completely back in control, and then it suddenly changes itself toFirst
-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
toSecond
is the same - The pop-transition from
Second
toFirst
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
toFirst
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屋!