IOS list diff library DifferenceKit example for Tableview

1. Install by adding this in your cocoapods Podfie and run pod install from the command line windown in your project directory.

pod 'DifferenceKit'

2. We need to wrap the data in ArraySection. ArraySection is provided by the DifferenceKit.

3. We need to implement the Differentiable for the data items that will be put into the ArraySection.

4. Here is an enum class for section categories.

import Foundation
import DifferenceKit

enum FoodCategory: String, Differentiable, CaseIterable {
    case Meat, Seafood, Vegetable, Fruit
}

5. Here is the custom object class implements Differentiable.

import Foundation
import DifferenceKit

struct FoodItem: Differentiable {
    var type: FoodCategory
    var name: String

    var differenceIdentifier: String {
        return name
    }

    func isContentEqual(to source: FoodItem) -> Bool {
        return name == source.name
    }
}

6. Here is a data factory class for creating the sample data to be used TableView. The data is wrapped in ArraySection.

import Foundation
import DifferenceKit

typealias FoodSection = ArraySection

struct DataFactory {
    
    static func createSampleData() -> [FoodSection] {
        let foodData = [
            (FoodCategory.Meat, ["Beef","Chicken","Lamb","Turkey", "Pork"]),
            (FoodCategory.Seafood, ["Fish","Shrimp","Crab", "Jellyfish"]),
            (FoodCategory.Fruit, ["Apple","Banana","Cherry", "Pineapple"]),
            (FoodCategory.Vegetable, ["Lettuce","Broccoli","Spinach", "Cauliflower"])
        ]
        
        var foodSections = [FoodSection]()
        
        for (key, values) in foodData {
            let foodItems = values
                .map { FoodItem(type: key, name: $0) }
                .shuffled()
                .prefix(upTo: Int(arc4random_uniform(UInt32(values.count))))
            if !foodItems.isEmpty { foodSections.append(FoodSection(model: key, elements: foodItems)) }
        }
        return foodSections
    }
    
}

7. Here is the table view controller FoodTableViewController. There properties, data and inputData, they hold the same value, data is used to retrieve data needed in the table view data source methods, inputData is used to update the data and in turn updates the tableview.

import UIKit
import DifferenceKit

class FoodTableViewController: UITableViewController {
    var data = [FoodSection]()
    var inputData: [FoodSection] {
        get {
            return data
        }
        set {
            //whenever the inputData gets assigned a newValue, this block of code will be executed and it will update the table view with the new set of data.
            let changeset = StagedChangeset(source: data, target: newValue)
            tableView.reload(using: changeset, with: .fade) { data in
                self.data = data
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        inputData = DataFactory.createSampleData()
    }

    @IBAction func refresh(_ sender: UIBarButtonItem) {
        inputData = DataFactory.createSampleData()
    }
    
    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return data.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data[section].elements.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
        cell.textLabel?.text = data[indexPath.section].elements[indexPath.row].name
        return cell
    }
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return data[section].model.rawValue
    }

}

Complete example in Github

DifferenceKit in Github

Search within Codexpedia

Custom Search

Search the entire web

Custom Search