我一直在寻找如何过渡/动画一个UINavigationBar
的barTintColor
,看到了不同的答案。有些人使用UIView.animateWithDuration
,有些人使用CATransition
,但最有趣的是像这个使用animate(alongsideTransition animation..
的方法,我很喜欢这种方法,但我无法使其正常工作。我做错了什么吗?
许多人指定我可以简单地在viewWillAppear:
中使用transitionCoordinator
,我已经像下面这样设置了一个全新超小项目:
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
}
}
First
到Second
的 push 转场看起来很完美。所有元素过渡得很好,除了状态栏外,它立即变成了白色。我更想知道如何转换它,但目前我会先接受它。Second
到First
的 pop 转场完全错误。它保留了Second
的颜色,直到转场完成。Second
到First
的拖动转场看起来还不错,只要一直拖到最后。同样地,当我开始拖动时,状态栏立即变成黑色,但我不知道是否可能修复。- 从
Second
到First
的拖动转场,但在中途取消并返回到Second
,则完全出现了问题。它看起来很好,直到Second
完全控制后,突然将自己更改为First
的颜色。这不应该发生。
我对我的 RootViewController
进行了一些改进,使其更好。我完全删除了 viewWillAppear:
,并用以下内容替换:
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
}
}
几点观察:
- 从
First
到Second
的过渡是一样的 - 从
Second
到First
的弹出式过渡现在已经正确地进行动画处理,除了后退箭头、后退文本(和状态栏,但是...)。它们会立即变成黑色。在第一个gif中,你可以看到后退箭头和后退文本也有过渡效果。 - 从
Second
到First
的拖拽式过渡也有这个问题,当开始时,后退箭头和后退文本会突然瞬间变成黑色。barTint被修复,以防止在取消拖拽时获得错误的颜色。
我做错了什么?我应该怎么做?
我的目标是平稳地过渡所有元素。返回按钮的色调、后退文本、标题、barTint和状态栏。这不可能吗?