iOS 8.0+ / OSX 10.9+ / watchOS 2.0+ • Swift 4.0 / Xcode 9+
To run the example project, clone the repo, and run pod install
from the Example directory first.
Import library for usage:
import NPTableAnimator
First of all, you need adopt your view model to TableAnimatorCell protocol:
struct MyViewModel: TableAnimatorCell {
let id: Int
var hashValue: Int {
return id.hashValue
}
var updateField: Date
static func == (lhs: MyViewModel, rhs: MyViewModel) -> Bool {
return lhs.id == rhs.id
}
}
For proper and fast animation calculating your view model should adopt to Equatable and Hashable protocols. So you tell to animator how to calculate changes between cells, but tables have sections too, so you had to provide that information to animator. Your section should adopt to TableAnimatorSection protocol.
• Note: even if you have only one section, you had to provide section too. Just set default value for updateField and pass true in coparing function.
struct MySection: TableAnimatorSection {
let id: Int
var cells: [MyCell]
var updateField: Int
static func == (lhs: MySection, rhs: MySection) -> Bool {
return lhs.id == rhs.id
}
}
Then you should create animator instance for calculating animations and build animations between two lists:
let animator = TableAnimator<MySection>()
let animations = try! animator.buildAnimations(from: currentList, to: newList)
animations struct got sections and cells insertions, deletions, updates and moves which you may pass for updates.
tableView.beginUpdates()
self.currentList = newList
tableView.insertSections(animations.sections.toInsert, with: .fade)
tableView.deleteSections(animations.sections.toDelete, with: .fade)
tableView.reloadSections(animations.sections.toUpdate, with: .fade)
for (from, to) in animations.sections.toMove {
tableView.moveSection(from, toSection: to)
}
tableView.reloadRows(animations.cells.toUpdate, with: .fade)
tableView.insertRows(at: animations.cells.toInsert, with: .fade)
tableView.deleteRows(at: animations.cells.toDelete, with: .fade)
tableView.reloadRows(at: animations.cells.toUpdate, with: .fade)
for (from, to) in animations.cells.toMove {
tableView.moveRow(at: from, to: to)
}
tableView.endUpdates()
// You should call .reloadRows(_:with:) in another update circle cause of UITableView update bugs...
// Animator provide all updates in toUpdate only if toInsert, toDelete and toUpdate are empty
// otherwise animator provides toDeferredUpdate array based on new cell indexes.
tableView.beginUpdates()
tableView.reloadRows(animations.cells.toDeferredUpdate, with: .fade)
tableView.endUpdates()
For your comfort animator may calculate and apply list. If you use code described above, you will see strange blink during update animation. Its not fatal but not cool. So animator may apply changes properly to your table. For that purposes you may use that code:
var currentList = [MySection]()
// Note: - currentList **not** changed to newList instantly. That function only start applying and
// adding request for change to newList into a queue.
tableView.apply(owner: self,
newList: newList,
animator: animator,
animated: true,
getCurrentListBlock: { $0.currentList },
setNewListBlock: { $0.currentList = $1 },
rowAnimation: .fade)
NPTableAnimator is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod "NPTableAnimator"
Also TableAnimator is available through Swift Package Manager. To install it, simply add the following line to your Package.swift:
.package(url: "https://github.com/Nekitosss/TableAnimator.git", from: "4.4.0")
// and
targets: [.target(name: "YourProject", dependencies: ["TableAnimator"])
Import library for usage:
import TableAnimator
Nikita Patskov, patskovn@yahoo.com
NPTableAnimator is available under the MIT license. See the LICENSE file for more info.