ios 在 Swift 中制作一个简单的淡入淡出动画?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24111770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Make a simple fade in animation in Swift?
提问by Benr783
I am trying to make a simple animation in Swift. It is a fade in.
我正在尝试在 Swift 中制作一个简单的动画。这是一个淡入。
I attempted:
我尝试:
self.myFirstLabel.alpha = 0
self.myFirstButton.alpha = 0
self.mySecondButton.alpha = 0
Then, I have:
然后,我有:
self.view.addSubview(myFirstLabel)
self.view.addSubview(myFirstButton)
self.view.addSubview(mySecondButton)
And then:
进而:
UIView.animateWithDuration(1.5, animations: {
self.myFirstLabel.alpha = 1.0
self.myFirstButton.alpha = 1.0
self.mySecondButton.alpha = 1.0
})
I have all of this in my viewDidLoad function.
我的 viewDidLoad 函数中包含所有这些。
How do I make this work?
我如何使这项工作?
回答by Mick MacCallum
The problem is that you're trying start the animation too early in the view controller's lifecycle. In viewDidLoad
, the view has just been created, and hasn't yet been added to the view hierarchy, so attempting to animate one of its subviews
at this point produces bad results.
问题是您试图在视图控制器的生命周期中过早地启动动画。在 中viewDidLoad
,视图刚刚创建,尚未添加到视图层次结构中,因此此时尝试为其之一设置动画subviews
会产生不好的结果。
What you really should be doing is continuing to set the alpha of the view in viewDidLoad
(or where you create your views), and then waiting for the viewDidAppear
: method to be called. At this point, you can start your animations without any issue.
您真正应该做的是继续在viewDidLoad
(或您创建视图的位置)中设置视图的 alpha ,然后等待viewDidAppear
: 方法被调用。此时,您可以毫无问题地开始动画。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 1.5) {
self.myFirstLabel.alpha = 1.0
self.myFirstButton.alpha = 1.0
self.mySecondButton.alpha = 1.0
}
}
回答by Luca Davanzo
0x7ffffff's answer is ok and definitely exhaustive.
0x7ffffff的回答没问题,而且绝对详尽。
As a plus, I suggest you to make an UIView extension, in this way:
另外,我建议您以这种方式制作 UIView 扩展:
public extension UIView {
/**
Fade in a view with a duration
- parameter duration: custom animation duration
*/
func fadeIn(duration duration: NSTimeInterval = 1.0) {
UIView.animateWithDuration(duration, animations: {
self.alpha = 1.0
})
}
/**
Fade out a view with a duration
- parameter duration: custom animation duration
*/
func fadeOut(duration duration: NSTimeInterval = 1.0) {
UIView.animateWithDuration(duration, animations: {
self.alpha = 0.0
})
}
}
Swift-3
斯威夫特-3
/// Fade in a view with a duration
///
/// Parameter duration: custom animation duration
func fadeIn(withDuration duration: TimeInterval = 1.0) {
UIView.animate(withDuration: duration, animations: {
self.alpha = 1.0
})
}
/// Fade out a view with a duration
///
/// - Parameter duration: custom animation duration
func fadeOut(withDuration duration: TimeInterval = 1.0) {
UIView.animate(withDuration: duration, animations: {
self.alpha = 0.0
})
}
In this way you can do this wherever in your code:
通过这种方式,您可以在代码中的任何位置执行此操作:
let newImage = UIImage(named: "")
newImage.alpha = 0 // or newImage.fadeOut(duration: 0.0)
self.view.addSubview(newImage)
...
newImage.fadeIn()
Code reuse is important!
代码重用很重要!
回答by budidino
Swiftonly solution
Swift唯一的解决方案
Similar to Luca's anwer, I use a UIView
extension. Compared to his solution I use DispatchQueue.main.async
to make sure animations are done on the main thread, alpha
parameter for fading to a specific value and optional duration
parameters for cleaner code.
与Luca 的 anwer类似,我使用了UIView
扩展名。与他的解决方案相比,我DispatchQueue.main.async
用来确保在主线程上完成动画、alpha
用于淡入淡出到特定值的duration
参数和用于更清晰代码的可选参数。
extension UIView {
func fadeTo(_ alpha: CGFloat, duration: TimeInterval = 0.3) {
DispatchQueue.main.async {
UIView.animate(withDuration: duration) {
self.alpha = alpha
}
}
}
func fadeIn(_ duration: TimeInterval = 0.3) {
fadeTo(1.0, duration: duration)
}
func fadeOut(_ duration: TimeInterval = 0.3) {
fadeTo(0.0, duration: duration)
}
}
How to use it:
如何使用它:
// fadeIn() - always animates to alpha = 1.0
yourView.fadeIn() // uses default duration of 0.3
yourView.fadeIn(1.0) // uses custom duration (1.0 in this example)
// fadeOut() - always animates to alpha = 0.0
yourView.fadeOut() // uses default duration of 0.3
yourView.fadeOut(1.0) // uses custom duration (1.0 in this example)
// fadeTo() - used if you want a custom alpha value
yourView.fadeTo(0.5) // uses default duration of 0.3
yourView.fadeTo(0.5, duration: 1.0)
回答by cs4alhaider
If you want repeatable fade animation you can do that by using CABasicAnimation
like below :
如果您想要可重复的淡入淡出动画,您可以使用CABasicAnimation
如下所示:
First create handy UIView extension :
首先创建方便的 UIView 扩展:
extension UIView {
enum AnimationKeyPath: String {
case opacity = "opacity"
}
func flash(animation: AnimationKeyPath ,withDuration duration: TimeInterval = 0.5, repeatCount: Float = 5){
let flash = CABasicAnimation(keyPath: animation.rawValue)
flash.duration = duration
flash.fromValue = 1 // alpha
flash.toValue = 0 // alpha
flash.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
flash.autoreverses = true
flash.repeatCount = repeatCount
layer.add(flash, forKey: nil)
}
}
How to use it:
如何使用它:
// You can use it with all kind of UIViews e.g. UIButton, UILabel, UIImage, UIImageView, ...
imageView.flash(animation: .opacity, withDuration: 1, repeatCount: 5)
titleLabel.flash(animation: .opacity, withDuration: 1, repeatCount: 5)
回答by LLIAJLbHOu
import UIKit
/*
Here is simple subclass for CAAnimation which create a fadeIn animation
*/
class FadeInAdnimation: CABasicAnimation {
override init() {
super.init()
keyPath = "opacity"
duration = 2.0
fromValue = 0
toValue = 1
fillMode = CAMediaTimingFillMode.forwards
isRemovedOnCompletion = false
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
/*
Example of usage
*/
class ViewController: UIViewController {
weak var label: UILabel!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = UILabel()
label.alpha = 0
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.text = "Hello World!"
label.textColor = .black
view.addSubview(label)
self.label = label
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 250, width: 300, height: 100)
button.setTitle("Press to Start FadeIn", for: UIControl.State())
button.backgroundColor = .red
button.addTarget(self, action: #selector(startFadeIn), for: .touchUpInside)
view.addSubview(button)
self.view = view
}
/*
Animation in action
*/
@objc private func startFadeIn() {
label.layer.add(FadeInAdnimation(), forKey: "fadeIn")
}
}
回答by nahung89
Swift 5
斯威夫特 5
Other answers are correct, but in my case I need to handle other properties also (alpha
, animate
, completion
). Because of this, I modified a bit to expose these parameters as below:
其他答案是正确的,但就我而言,我还需要处理其他属性 ( alpha
, animate
, completion
)。因此,我修改了一些以公开这些参数,如下所示:
extension UIView {
/// Helper function to update view's alpha with animation
/// - Parameter alpha: View's alpha
/// - Parameter animate: Indicate alpha changing with animation or not
/// - Parameter duration: Indicate time for animation
/// - Parameter completion: Completion block after alpha changing is finished
func set(alpha: CGFloat, animate: Bool, duration: TimeInterval = 0.3, completion: ((Bool) -> Void)? = nil) {
let animation = { (view: UIView) in
view.alpha = alpha
}
if animate {
UIView.animate(withDuration: duration, animations: {
animation(self)
}, completion: { finished in
completion?(finished)
})
} else {
layer.removeAllAnimations()
animation(self)
completion?(true)
}
}
}