在Swift的导航栏中对图像进行动画处理

时间:2018-11-07 11:01:00

标签: ios swift animation uinavigationbar

我在情节提要中创建的ViewController的导航栏中有一个图像,并为该图像提供了一个属性奥特莱斯,并希望动画过渡到另一个图像。使用过渡会以模态方式启动视图控制器。

通过更改图像的Alpha值可以动画化图像的褪色没有问题。但是,如果我更改图像而不是使其褪色,则没有动画。而是在页面加载后立即显示新图像。无论我将动画代码放在viewDidLoad还是viewWillAppear中都是如此。我希望该动画仅在加载视图时发生一次,但是,我在viewWillAppear中尝试了一下,只是想看看是否能完全获得效果。

这是我的代码

// in viewdidload or viewwillappear
   let newImage = UIImage(named: "headshot.png")
    UIView.transition(with: self.imageView,
                      duration:0.5,
                      options: .transitionCrossDissolve,
                      animations: { self.ImageView.image = newImage },
                      completion: nil)

使导航栏中的图像相对于常规视图有特殊的动画吗?还是我需要做些什么来使导航栏中的图像变化动起来?

1 个答案:

答案 0 :(得分:1)

您的图片未设置动画的原因是,从编译器的角度来看,用另一图片替换图片(就像插入图片一样)是 atomic 动作。这意味着self.ImageView.image = newImage是一步完成的一行。也就是说,在任何时候,您的imageView都将newImage作为其image属性,或者没有。像原子一样发生的状态变化无法随时间变化。

另一种查看方式是,为了将动画的持续时间更改为0.5秒(而不是一步一步地自动执行此操作),XCode编译器必须按字面意义放置图像在imageView秒内零零碎碎地出现在您的0.5中。显然,这是不确定的行为。编译器如何知道什么时候将图像的哪些部分放置在屏幕上?

一个简单的解决方案是将两个单独的imageView(放置在屏幕上的同一位置)(其中一个开始透明)。 imageView中的每一个都有一个单独的图像,您可以通过简单地淡出一个图像然后淡入另一个图像来在这两个图像之间转换,就像这样:

class viewController: UIViewController {
    let imageView1 = UIImageView("headshot1.png")
    let imageView2 = UIImageView("headshot2.png")

    override viewDidLoad() {
        super.viewDidLoad()

        /* add imageViews to your view and place them both 
           in the middle of the screen */
        imageView1.translatesAutoresizingMaskIntoConstraints = false
        imageView1.alpha = 1.0
        self.addSubview(imageView1)

        /* notice that this imageView is completely transparent */
        imageView2.translatesAutoresizingMaskIntoConstraints = false
        imageView2.alpha = 0.0
        self.addSubview(imageView2)

        /* place both imageViews in the middle of your screen,
           with imageView1 completely visible and imageView2
           completely transparent */
        imageView1.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        imageView1.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true

        imageView2.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        imageView2.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true

        // fade out first imageView
        UIView.animate(withDuration: 0.25) {
        imageView1.alpha = 0.0
        }

        // fade in second imageView
        UIView.animate(withDuration: 0.25) {
        imageView2.alpha = 1.0
        }
    }
}

您也可以使用transition函数代替animate函数-逻辑实际上是相同的。