Я пытаюсь сделать простую анимацию на Swift. Это угасание.
Я пытался:
self.myFirstLabel.alpha = 0
self.myFirstButton.alpha = 0
self.mySecondButton.alpha = 0
Тогда у меня есть:
self.view.addSubview(myFirstLabel)
self.view.addSubview(myFirstButton)
self.view.addSubview(mySecondButton)
А потом:
UIView.animateWithDuration(1.5, animations: {
self.myFirstLabel.alpha = 1.0
self.myFirstButton.alpha = 1.0
self.mySecondButton.alpha = 1.0
})
Все это есть у меня в функции viewDidLoad.
Как мне заставить это работать?
viewWillAppear
илиviewDidAppear
поскольку вы не знаете, что происходит между загрузкой и отображением представления.Ответы:
Проблема в том, что вы пытаетесь запустить анимацию слишком рано в жизненном цикле контроллера представления. В
viewDidLoad
, представление было только что создано и еще не добавлено в иерархию представлений, поэтому попытка анимировать одно из представленийsubviews
на этом этапе дает плохие результаты.Что вам действительно нужно делать, так это продолжать устанавливать альфа-канал представления
viewDidLoad
(или места, где вы создаете свои представления), а затем ждать вызова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 } }
источник
viewWillAppear
более подходящим для этого?UIView.animateWithDuration(1.5, animations: { self.myFirstLabel.alpha = 1.0 return })
0x7ffffff порядке и определенно исчерпывающий.
В качестве плюса я предлагаю вам сделать расширение 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 }) } }
Стриж-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 }) }
Таким образом, вы можете сделать это в любом месте вашего кода:
let newImage = UIImage(named: "") newImage.alpha = 0 // or newImage.fadeOut(duration: 0.0) self.view.addSubview(newImage) ... newImage.fadeIn()
Повторное использование кода важно!
источник
Только быстрое решение
Как и в ответе Луки , я использую
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) } }
Как это использовать:
// 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)
источник
Если вам нужна повторяемая анимация затухания, вы можете сделать это, используя,
CABasicAnimation
как показано ниже:Сначала создайте удобное расширение 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) } }
Как это использовать:
// 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)
источник
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") } }
источник
Swift 5
Другие ответы правильны, но в моем случае мне нужно обращаться с другими свойствами и (
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) } } }
источник