Swift 中导航栏中图像的动画变化
Animate change of image in Navigation Bar in Swift
我在情节提要中创建的 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)
相对于常规视图,在导航栏中为图像设置动画有什么特别之处吗?或者我需要做什么来使导航栏中的图像变化动画化?
你的图像没有动画的原因是因为从编译器的角度来看,用另一个图像替换另一个图像(就像插入图像一样)是一个 atomic 动作。这意味着 self.ImageView.image = newImage
是一步中发生的一行。也就是说,在任何时间点,您的 imageView
要么具有 newImage
作为其 image
属性,要么没有。像这样以原子方式发生的状态变化不能随着时间的推移而变化。
另一种看待它的方式是,为了将动画的持续时间更改为 0.5
秒(而不是在单个步骤中自动执行此操作),XCode 编译器将必须在 0.5
秒内将图像逐字逐句地放入 imageView
中。显然,这是未定义的行为。编译器如何知道在什么时间将图像的哪些部分放在屏幕上?
解决您的问题的一个简单方法是将两个单独的 imageView
s - 其中一个一开始是透明的 - 放置在屏幕上完全相同的位置。 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
函数 - 逻辑几乎相同。
我在情节提要中创建的 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)
相对于常规视图,在导航栏中为图像设置动画有什么特别之处吗?或者我需要做什么来使导航栏中的图像变化动画化?
你的图像没有动画的原因是因为从编译器的角度来看,用另一个图像替换另一个图像(就像插入图像一样)是一个 atomic 动作。这意味着 self.ImageView.image = newImage
是一步中发生的一行。也就是说,在任何时间点,您的 imageView
要么具有 newImage
作为其 image
属性,要么没有。像这样以原子方式发生的状态变化不能随着时间的推移而变化。
另一种看待它的方式是,为了将动画的持续时间更改为 0.5
秒(而不是在单个步骤中自动执行此操作),XCode 编译器将必须在 0.5
秒内将图像逐字逐句地放入 imageView
中。显然,这是未定义的行为。编译器如何知道在什么时间将图像的哪些部分放在屏幕上?
解决您的问题的一个简单方法是将两个单独的 imageView
s - 其中一个一开始是透明的 - 放置在屏幕上完全相同的位置。 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
函数 - 逻辑几乎相同。