【问题标题】:iOS 10 barTintColor animationiOS 10 barTintColor 动画
【发布时间】:2017-02-05 07:25:54
【问题描述】:

我注意到 ios 10 中条形颜色动画的方式发生了变化。我创建了一个示例项目来概述更改:Github: ios10BarTintDemo

基本上在 ios 9 上,barTintColor 使用 [UIViewControllerTransitionCoordinator animateAlongsideTransition] 平滑动画

但在 ios 10 上,动画不太流畅,并且在弹出视图控制器时根本没有动画,我尝试添加 [self.navigationController.navigationBar layoutIfNeeded],如一些类似答案中所述,但这似乎没有任何效果推/弹出控制器时。

【问题讨论】:

  • 你找到解决这个问题的方法了吗?
  • 还没有,还在摸索中,找到解决方案后会在这里更新。

标签: ios objective-c iphone animation ios10


【解决方案1】:

更新

我在 iOS 10.3 中进行了测试,我认为问题已得到解决。 transitionCordinator 不再需要。我觉得动画很流畅。请查看我的project on 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
    }
}

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

要实现这种动画,你应该使用UIViewControllerTransitionCoordinator as Apple documentation 说它是:

采用 UIViewControllerTransitionCoordinator 协议的对象为与视图控制器转换关联的动画提供支持。(...)

所以每个UIViewController 都有自己的transitionController。要得到这个,你应该打电话给UIViewControllerClass

self.transitionCoordinator()

来自documentation

返回活动转换协调器对象。

所以要得到你想要的结果,你应该在 viewController transitionCoordinatior 中实现animateAlongsideTransition 方法。当您单击backButton 并向后滑动时,动画会起作用。

例子:

第一个控制器:

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
    }
}

第二控制器:

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
    }

}

更新 iOS 10

在 iOS 10 中,棘手的部分是在 second ViewController 中添加 willMoveTo(parentViewController parent: UIViewController?)。并将 navigationBar tintColor 设置为 previous 控制器的颜色值。此外,在 second ViewControler 中的 viewDidAppear 方法中,将 navigationBar.tintColor 设置为来自 second viewController 的颜色。

看看我的例子project on github

【讨论】:

  • 谢谢!没想到使用以前的颜色会移动到父级
  • 非常感谢,我错过了 willMoveToParent 覆盖,这会在点击后退按钮时导致奇怪的颜色跳跃。
  • 这看起来很棒。但是有一个问题,我怎么知道我可以用这种技术制作什么动画?它就像 barTintColor 的魅力一样,但我似乎无法通过更改添加到 UINavigationBar 的子视图的 backgroundColor 来做同样的事情。我什至拿了你的 github 项目并在那里工作,但没有运气......
  • if navigationBar.isTranslucent == false 然后改变颜色有延迟,这不起作用
  • @Chlebta 你解决了这个问题吗?
【解决方案2】:

您可以通过添加与此类似的内容来解决此弹出问题,在 iOS10 中由于某种原因在 viewWillDisappear 中运行它将不起作用

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

【讨论】:

  • 我尝试将其添加到示例项目中,但似乎没有帮助,它对您有用吗?
猜你喜欢
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多