Ich versuche eine einfache Animation in Swift zu erstellen. Es ist ein Einblenden.
Ich versuchte:
self.myFirstLabel.alpha = 0
self.myFirstButton.alpha = 0
self.mySecondButton.alpha = 0
Dann habe ich:
self.view.addSubview(myFirstLabel)
self.view.addSubview(myFirstButton)
self.view.addSubview(mySecondButton)
Und dann:
UIView.animateWithDuration(1.5, animations: {
self.myFirstLabel.alpha = 1.0
self.myFirstButton.alpha = 1.0
self.mySecondButton.alpha = 1.0
})
Ich habe all dies in meiner viewDidLoad-Funktion.
Wie mache ich das?
viewWillAppear
oderviewDidAppear
weil Sie nicht wissen, was zwischen dem Laden und Anzeigen der Ansicht passiert.Antworten:
Das Problem ist, dass Sie versuchen, die Animation zu früh im Lebenszyklus des View Controllers zu starten. In
viewDidLoad
wurde die Ansicht gerade erstellt und noch nicht zur Ansichtshierarchie hinzugefügt. Der Versuch, einesubviews
dieser Ansichten zu animieren, führt daher zu schlechten Ergebnissen.Was Sie wirklich tun sollten, ist weiterhin das Alpha der Ansicht festzulegen
viewDidLoad
(oder wo Sie Ihre Ansichten erstellen) und dann auf denviewDidAppear
Aufruf der Methode: zu warten . An diesem Punkt können Sie Ihre Animationen ohne Probleme starten.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 } }
quelle
viewWillAppear
besser geeignet?UIView.animateWithDuration(1.5, animations: { self.myFirstLabel.alpha = 1.0 return })
Die Antwort von 0x7ffffff ist in Ordnung und definitiv erschöpfend.
Als Plus empfehle ich Ihnen, eine UIView-Erweiterung auf folgende Weise zu erstellen:
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
/// 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 }) }
Auf diese Weise können Sie dies überall in Ihrem Code tun:
let newImage = UIImage(named: "") newImage.alpha = 0 // or newImage.fadeOut(duration: 0.0) self.view.addSubview(newImage) ... newImage.fadeIn()
Die Wiederverwendung von Code ist wichtig!
quelle
Schnelle Lösung
Ähnlich wie bei Lucas Antwort verwende ich eine
UIView
Erweiterung. Im Vergleich zu seiner LösungDispatchQueue.main.async
stelle ich sicher, dass Animationen im Hauptthread ausgeführt werden,alpha
Parameter zum Überblenden auf einen bestimmten Wert und optionaleduration
Parameter für saubereren Code.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) } }
Wie man es benutzt:
// 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)
quelle
Wenn Sie wiederholbare Überblendungsanimationen wünschen, können Sie dies
CABasicAnimation
wie folgt tun :Erstellen Sie zuerst eine praktische UIView-Erweiterung:
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) } }
Wie man es benutzt:
// 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)
quelle
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") } }
quelle
Swift 5
Andere Antworten sind richtig, aber in meinem Fall muss ich andere Eigenschaften zu handhaben auch (
alpha
,animate
,completion
). Aus diesem Grund habe ich ein wenig geändert, um diese Parameter wie folgt verfügbar zu machen: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) } } }
quelle