简体   繁体   English

iOS 10 barTintColor动画

[英]iOS 10 barTintColor animation

I've noticed a change in the way bar tint color animates in ios 10. I've created a sample project outlining the change: Github: ios10BarTintDemo 我注意到ios 10中条形色调动画的方式发生了变化。我创建了一个概述更改的示例项目: Github:ios10BarTintDemo

Basically on ios 9 the barTintColor animates smoothly using [UIViewControllerTransitionCoordinator animateAlongsideTransition] 基本上在ios 9上,barTintColor使用[UIViewControllerTransitionCoordinator animateAlongsideTransition]平滑动画

but on ios 10 the animations are much less smooth and when popping a view controller doesn't animate at all, I've tried adding [self.navigationController.navigationBar layoutIfNeeded] as mentioned in some similar answers but this doesn't seem to have any effect when pushing/popping controllers. 但是在ios 10上,动画不太流畅,当弹出一个视图控制器根本没有动画时,我尝试添加[self.navigationController.navigationBar layoutIfNeeded]正如一些类似的答案中提到的那样,但这似乎没有推/弹控制器时的任何效果。

UPDATE UPDATE

I've tested in iOS 10.3 and I think the problem was fixed. 我已经在iOS 10.3中测试过,我认为问题已得到修复。 And transitionCordinator is no need anymore. 并且不再需要transitionCordinator I think the animation is smooth. 我觉得动画很流畅。 Please check my project on github or look at this code: 请检查我在github上的项目或查看此代码:

class ViewControllerA: UIViewController {

    override func loadView() {
        super.loadView()
        title = "A"
        view.backgroundColor = .white
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "NEXT", style: .plain, target: self, action: #selector(self.showController))
    }

    override func viewWillAppear(_ animated: Bool) {
        setColors()
        super.viewWillAppear(animated)
    }

    func showController() {
        navigationController?.pushViewController(ViewControllerB(), animated: true)
    }

    private func setColors() {
        navigationController?.navigationBar.tintColor = .black
        navigationController?.navigationBar.barTintColor = .red
        navigationController?.navigationBar.isTranslucent = false
    }
}




class ViewControllerB: UIViewController {

    override func loadView() {
        super.loadView()
        title = "B"
        view.backgroundColor = .white
    }

    override func viewWillAppear(_ animated: Bool) {
        setColors()
        super.viewWillAppear(animated)
    }

    override func willMove(toParentViewController parent: UIViewController?) {
        if parent == nil {
            navigationController?.navigationBar.barTintColor = .red
        }
        super.willMove(toParentViewController: parent)
    }


    private func setColors() {
        navigationController?.navigationBar.tintColor = .black
        navigationController?.navigationBar.barTintColor = .blue
        navigationController?.navigationBar.isTranslucent = false
    }
}

============================================================================================================================================================================================================================================================================================================ ================================================== ================================================== ================================================== ================================================== ================================================== ==================================================

To achieve this kind of animation you should use UIViewControllerTransitionCoordinator as Apple documentation say it is : 要实现这种动画,您应该使用UIViewControllerTransitionCoordinator因为Apple文档说它是:

An object that adopts the UIViewControllerTransitionCoordinator protocol provides support for animations associated with a view controller transition.(...) 采用UIViewControllerTransitionCoordinator协议的对象为与视图控制器转换关联的动画提供支持。(...)

So every UIViewController has own transitionController . 所以每个UIViewController都有自己的transitionController To get this you should call in the UIViewControllerClass : 要获得这个,你应该调用UIViewControllerClass

self.transitionCoordinator()

From documentation : 来自文档

Returns the active transition coordinator object. 返回活动的转换协调器对象。

So to get the result that you want you should implement animateAlongsideTransition method in viewController transitionCoordinatior. 因此,要获得您想要的结果,您应该在viewController transitionCoordinatior中实现animateAlongsideTransition方法。 Animation works when you click backButton and swipe to back. 单击backButton并向后滑动时,动画可以正常工作。

Example : 示例:

navigation_bar_animation

First Controller : 第一控制员:

class ViewControllerA: UIViewController {

    override func loadView() {
        super.loadView()
        title = "A"
        view.backgroundColor = .white
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "NEXT", style: .plain, target: self, action: #selector(self.showController))
        setColors()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        animate()
    }

    func showController() {
        navigationController?.pushViewController(ViewControllerB(), animated: true)
    }

    private func animate() {
        guard let coordinator = self.transitionCoordinator else {
            return
        }

        coordinator.animate(alongsideTransition: {
            [weak self] context in
            self?.setColors()
        }, completion: nil)
    }

    private func setColors() {
        navigationController?.navigationBar.tintColor = .black
        navigationController?.navigationBar.barTintColor = .red
    }
}

Second Controller: 第二控制器:

class ViewControllerB : UIViewController {

    override func loadView() {
        super.loadView()
        title = "B"
        view.backgroundColor = .white
        setColors()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        animate()
    }

    override func willMove(toParentViewController parent: UIViewController?) { // tricky part in iOS 10
        navigationController?.navigationBar.barTintColor = .red //previous color
        super.willMove(toParentViewController: parent)
    }

    override func viewDidAppear(_ animated: Bool) {
        navigationController?.navigationBar.barTintColor = .blue
    }

    private func animate() {
        guard let coordinator = self.transitionCoordinator else {
            return
        }
        coordinator.animate(alongsideTransition: {
            [weak self] context in
            self?.setColors()
        }, completion: nil)
    }

    private func setColors(){
        navigationController?.navigationBar.tintColor = .black
        navigationController?.navigationBar.barTintColor = .blue
    }

}

UPDATE iOS 10 更新iOS 10

In the iOS 10 the tricky part is to add the willMoveTo(parentViewController parent: UIViewController?) in the second ViewController. 在iOS 10中,棘手的部分是在第二个 ViewController中添加willMoveTo(parentViewController parent: UIViewController?) And set the navigationBar tintColor to the color value of previous controller. 并将navigationBar tintColor设置为上一个控制器的颜色值。 Also, in viewDidAppear method in second ViewControler set the navigationBar.tintColor to the color from second viewController. 另外,在第二个 ViewControler的viewDidAppear方法中,将navigationBar.tintColor设置为第二个 viewController的颜色。

Check out my example project on github 在github上查看我的示例项目

You can fix this popping issue by adding something similar to this, running it in viewWillDisappear won't work for some reason in iOS10 您可以通过添加类似于此的内容来修复此弹出问题,在viewWillDisappear中运行它将因iOS10中的某些原因而无法正常工作

override func willMove(toParentViewController parent: UIViewController?) {
    self.navigationController?.navigationBar.barTintColor = UIColor.red
    super.willMove(toParentViewController: parent)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM