Skip to content

Instantly share code, notes, and snippets.

@michaelevensen
Created December 4, 2019 14:57
Show Gist options
  • Save michaelevensen/21211862f51566e352ff75544503a021 to your computer and use it in GitHub Desktop.
Save michaelevensen/21211862f51566e352ff75544503a021 to your computer and use it in GitHub Desktop.
Dynamic updating of UITableView with FireStore changes.
func dataSourceForQuery(_ query: Query) -> CategorySessionsTableViewDataSource {
return CategorySessionsTableViewDataSource(query: query) { (changes, sessions) in
// Success: Perform batch remove / insert of cells
if #available(iOS 11.0, *) {
self.tableView.performBatchUpdates({
self.performUpdates(for: changes)
}, completion: nil)
}
// Fallback on earlier versions
else {
self.tableView.beginUpdates()
self.performUpdates(for: changes)
self.tableView.endUpdates()
}
// Dismiss Activity Loader
self.dismissActivity()
}
}
/// Performs needed UI updates based on `DocumentChange`'s in TableView
fileprivate func performUpdates(for changes: [DocumentChange]) {
guard let totalRowCount = self.dataSource?.count else {
return
}
changes.forEach { (change) in
switch change.type {
case .added:
// Only insert if needed
if self.tableView.numberOfRows(inSection: 0) < totalRowCount {
self.tableView.insertRows(at: [IndexPath(row: Int(change.newIndex), section: 0)], with: .top)
}
case .removed:
self.tableView.deleteRows(at: [IndexPath(row: Int(change.oldIndex), section: 0)], with: .top)
case .modified:
self.tableView.reloadRows(at: [IndexPath(row: Int(change.newIndex), section: 0)], with: .automatic)
}
}
}
@michaelevensen
Copy link
Author

And here is UICollectionView:

 func dataSourceForQuery(_ query: Query) -> FeaturedSessionsCollectionViewDataSource {
        return FeaturedSessionsCollectionViewDataSource(query: query) { (changes, sessions) in
            
            // Dismiss Loader
            self.dismissActivity()
            
            // Perform batch insertion, updating, removal of cells based on changes.
            self.collectionView?.performBatchUpdates({
                changes.forEach { (change) in
                    
                    switch change.type {
                    case .added:
                        
                        // Only insert if needed
                        if let collectionViewItemCount = self.collectionView?.numberOfItems(inSection: 0),
                            collectionViewItemCount < sessions.count {
                            self.collectionView?.insertItems(at: [IndexPath(row: Int(change.newIndex), section: 0)])
                        }
                        
                    case .removed:
                        self.collectionView?.deleteItems(at: [IndexPath(row: Int(change.oldIndex), section: 0)])
                    
                    case .modified:
                        self.collectionView?.reloadItems(at: [IndexPath(row: Int(change.newIndex), section: 0)])
                    }
                }
            }, completion: nil)
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment