Classes
The following classes are available globally.
-
Default
DiffableDataSource
that provides the logic to section provides updates toxDiffCollection
that is used as a Backstorage those updates are used byDiffableTableViewDataSource
to tellUITableView
what to reload,insert or deleteDeclaration
Swift
public class DiffableDataSource : NSObject
-
Class adapter to provide section filter. Based on the filter function
DiffableDataSource
decides what goes into a particular section.- Generic type
T
stands for type of a model. - Generic type
S
stands for the unique ID of a Section
Usage Example
- Assuming we have the next model:
See moreenum TextModelMockType: String { case type1 case type2 case type3 } /// Type represent unique item /// Text is something that is dynamic and can be changed struct TextModelMock: Hashable { let text: String let type: TextModelMockType func hash(into hasher: inout Hasher) { hasher.combine(type) } static func == (lhs: Self, rhs: Self) -> Bool { lhs.text == rhs.text } }
Declaration
Swift
public final class DiffableDataSourceFilter<T, S> where T : Hashable, S : Hashable
- Generic type
-
Class - container that allows to append different type of filters Used during initialization of
See moreDiffableDataSource
Declaration
Swift
public class DiffableDataSourceFilterProvider
-
Generic class that represents suggested updates to the
See moreDiffableDataSource
Declaration
Swift
open class GenericSectionUpdate<RowModel, SectionID> where RowModel: Hashable, SectionID: Hashable
-
The core of
EZSource
forUITableView
. Provides declarative API to work withUITableView
All you need is to initialize the source, create rows, add them to section updates and call update function The rest is handled byEZSource
, next time you have to update theUITableView
,EZSource
will find take care about inserting, deleting or reloading rows using animation provided in the section updatesUsage Example
- Define a Cell Model
struct StringCellModel: Hashable { let uniqueID: String let text: String // Defines uniqueness of the model func hash(into hasher: inout Hasher) { hasher.combine(uniqueID) } // Defines dynamic context of the model static func == (lhs: Self, rhs: Self) -> Bool { lhs.text == rhs.text } }
- Define a Cell
final class StringCell: UITableViewCell, ReusableCell, Configurable { typealias Model = StringCellModel func configure(with model: StringCellModel) { textLabel?.text = "ID: \(model.uniqueID): \(model.text)" selectionStyle = .none } }
- Create Data Source
let config = DiffableTableViewDataSource.Config(tableView: tableView, cellTypes: [StringCell.self], headerFooters: [TestReusableView.self]) source = DiffableTableViewDataSource(config: config)
- create a
TableViewRow
let model = StringCellModel(uniqueID: ID, text: title) let row = TableViewRow<StringCell>(model: model, onTap: { debugPrint("tapped with \($0)")}) // add rows if need row.addRowLeadingActions(leadingActions) row.addRowTrailingActions(trailingActions)
- Add the row to the cell
let updates = TableViewDiffableSection(id: "SectionID here") updates.addRows([row])
- Create a ReusableView
final class TestReusableView: ReusableView, Configurable { let label: UILabel override init(reuseIdentifier: String?) { // Init and Configure UILabel super.init(reuseIdentifier: reuseIdentifier) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } func configure(with txt: String) { label.text = txt } }
- Create a header
let text = "My custom section" let footer = ImmutableHeaderFooterProvider<TestReusableView>(model: text)
- Attach the header to a
TableViewDiffableSection
let updates = TableViewDiffableSection(id: "SectionID here") updates.addHeader(header)
- Call updates on the source
See moresource.update(sections: [updates])
Declaration
Swift
public final class DiffableTableViewDataSource : DiffableDataSource
extension DiffableTableViewDataSource: UITableViewDataSource
extension DiffableTableViewDataSource: UITableViewDelegate
-
Represents changes proposed to a section Example
- Define a Cell Model
struct StringCellModel: Hashable { let uniqueID: String let text: String // Defines uniqueness of the model func hash(into hasher: inout Hasher) { hasher.combine(uniqueID) } // Defines dynamic context of the model static func == (lhs: Self, rhs: Self) -> Bool { lhs.text == rhs.text } }
- Define a Cell
final class StringCell: UITableViewCell, ReusableCell, Configurable { typealias Model = StringCellModel func configure(with model: StringCellModel) { textLabel?.text = "ID: \(model.uniqueID): \(model.text)" selectionStyle = .none } }
- create a
TableViewRow
let model = StringCellModel(uniqueID: ID, text: title) let row = TableViewRow<StringCell>(model: model, onTap: { debugPrint("tapped with \($0)")}) // add rows if need row.addRowLeadingActions(leadingActions) row.addRowTrailingActions(trailingActions)
- Add the row to the cell
let updates = TableViewDiffableSection(id: "SectionID here") updates.addRows([row])
- Create a ReusableView
final class TestReusableView: ReusableView, Configurable { let label: UILabel override init(reuseIdentifier: String?) { // Init and Configure UILabel super.init(reuseIdentifier: reuseIdentifier) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } func configure(with txt: String) { label.text = txt } }
- Create a header
let text = "My custom section" let footer = ImmutableHeaderFooterProvider<TestReusableView>(model: text)
- Attach the header to a
TableViewDiffableSection
See morelet updates = TableViewDiffableSection(id: "SectionID here") updates.addHeader(header)
Declaration
Swift
public final class TableViewDiffableSection : GenericSectionUpdate<AnyHashable, String>
-
The absctract class to provide a section header or footer view
Warning:
Using this class as is will cause a CRASH
See moreDeclaration
Swift
public class HeaderFooterProvider<View>: SectionHeaderFooterProvider where View: Configurable & ReusableView
-
Default class that is responsible to dequeue a reusable view and configure it
Note
if the height is nil then you should make UIView as a self-sized viewUsage Example
- Create a ReusableView
final class TestReusableView: ReusableView, Configurable { let label: UILabel override init(reuseIdentifier: String?) { // Init and Configure UILabel super.init(reuseIdentifier: reuseIdentifier) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } func configure(with txt: String) { label.text = txt } }
- Create a header
let text = "My custom section" let header = ImmutableHeaderFooterProvider<TestReusableView>(model: text)
- Attach the header to a
TableViewDiffableSection
See morelet updates = TableViewDiffableSection(id: "SectionID here") updates.addHeader(header)
Declaration
Swift
public class ImmutableHeaderFooterProvider<View>: HeaderFooterProvider<View> where View: Configurable & ReusableView
-
Default class that is responsible to dequeue a reusable view and configure it In addition provides an update method to change the model.
Note
if the height is nil then you should make UIView as a self-sized viewUsage Example
- Create a ReusableView
final class TestReusableView: ReusableView, Configurable { let label: UILabel override init(reuseIdentifier: String?) { // Init and Configure UILabel super.init(reuseIdentifier: reuseIdentifier) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } func configure(with txt: String) { label.text = txt } }
- Create a header
let text = "My custom section" // Store the header so you can reference to it later let header = MutableHeaderFooterProvider<TestReusableView>(model: text)
- Attach the header to a
TableViewDiffableSection
and update after calling datasource update
See morelet updates = TableViewDiffableSection(id: "SectionID here") updates.addHeader(header) // call datasource update header.update(model: "New text here")
Declaration
Swift
public class MutableHeaderFooterProvider<View>: HeaderFooterProvider<View> where View: Configurable & ReusableView
-
Higher-API class for UIContextualAction
See more**Example Usage** - Create Action ```` var rowAction: RowAction { RowAction { [weak self] in guard let `self` = self else { return } let alertController = self.alertControllerExample let act = self.dismissAction(for: alertController) alertController.addAction(act) self.present(alertController, animated: true, completion: nil) } } ```` - set up title and color ```` var leadingActions: [RowAction] { let action = rowAction action.backgroundColor = .green action.title = "Done" return [action] } ```` - add to a row ```` let model = StringCellModel(uniqueID: ID, text: title) let row = TableViewRow<StringCell>(model: model, onTap: { debugPrint("tapped with \($0)")}) row.addRowLeadingActions(leadingActions) ````
Declaration
Swift
public class RowAction
-
The concept of a generic TableViewCell:
- it knows about model it operates with
- contains tap closure that is called when a cell is tapped
- responsible for dequeueing a cell
- provides methods to add leading / trailing actions
Example
- Define a Cell Model
struct StringCellModel: Hashable { let uniqueID: String let text: String // Defines uniqueness of the model func hash(into hasher: inout Hasher) { hasher.combine(uniqueID) } // Defines dynamic context of the model static func == (lhs: Self, rhs: Self) -> Bool { lhs.text == rhs.text } }
- Define a Cell
final class StringCell: UITableViewCell, ReusableCell, Configurable { typealias Model = StringCellModel let checkmarkView = UIView() func configure(with model: StringCellModel) { textLabel?.text = "ID: \(model.uniqueID): \(model.text)" selectionStyle = .none } override var isSelected: Bool { didSet { debugPrint(isSelected) } } override func prepareForReuse() { accessoryType = .none } override func setSelected(_ selected: Bool, animated: Bool) { if selected { accessoryType = .checkmark } else { accessoryType = .none } super.setSelected(selected, animated: animated) } }
- create a
TableViewRow
See morelet model = StringCellModel(uniqueID: ID, text: title) let row = TableViewRow<StringCell>(model: model, onTap: { debugPrint("tapped with \($0)")}) // add rows if need row.addRowLeadingActions(leadingActions) row.addRowTrailingActions(trailingActions)
Declaration
Swift
public class TableViewRow<Cell> : CellProvider where Cell : UITableViewCell, Cell : Configurable, Cell : Reusable
extension TableViewRow: Hashable, Equatable where Cell.Model: Hashable & Equatable