I need to animate the load of the table view rows. When the table reloads the data I need the rows get in from the left one after another. How can I achieve this?
None of the solutions provided helped me so I came up with my own. Here's a little general purpose class that can be used to chain animations together and play them one after another. It's syntax is similar to that of the UIView.animate() and once called, asynchronously queues the animation and then begins executing the queue in a sequential manner in the order they were added:
import UIKit
import Foundation
class ChainedAnimationsQueue {
private var playing = false
private var animations = [(TimeInterval, () -> Void, () -> Void)]()
init() {
}
/// Queue the animated changes to one or more views using the specified duration and an initialization block.
///
/// - Parameters:
/// - duration: The total duration of the animations, measured in seconds. If you specify a negative value or 0, the changes are made without animating them.
/// - initializations: A block object containing the changes to commit to the views to set their initial state. This block takes no parameters and has no return value. This parameter must not be NULL.
/// - animations: A block object containing the changes to commit to the views. This is where you programmatically change any animatable properties of the views in your view hierarchy. This block takes no parameters and has no return value. This parameter must not be NULL.
func queue(withDuration duration: TimeInterval, initializations: @escaping () -> Void, animations: @escaping () -> Void) {
self.animations.append((duration, initializations, animations))
if !playing {
playing = true
DispatchQueue.main.async {
self.next()
}
}
}
private func next() {
if animations.count > 0 {
let animation = animations.removeFirst()
animation.1()
UIView.animate(withDuration: animation.0, animations: animation.2, completion: { finished in
self.next()
})
} else {
playing = false
}
}
}
var animationsQueue = ChainedAnimationsQueue()
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.alpha = 0.0
animationsQueue.queue(withDuration: 0.2, initializations: {
cell.layer.transform = CATransform3DTranslate(CATransform3DIdentity, cell.frame.size.width, 0, 0)
}, animations: {
cell.alpha = 1.0
cell.layer.transform = CATransform3DIdentity
})
}