If you like the project, please give it a star ⭐ It will show your appreciation and help others to discover this repo.
🪶 Lightweight, reusable, generic NSDiffableDataSource-backed view models for UICollectionView and UITableView, intended to help simplify implementing Diffable Data Sources in Swift/UIKit apps.
- Lightweight
- Two Protocols. Two Classes. Two Reusable Views. One Purpose.
- Flexible
- Use the provided convenience methods, or
- Easily override default behavior to suit your specific needs.
- Generic view model classes for both UITableView and UICollectionView eliminate the need for most boilerplate.
- Protocols for Section and ItemType + take the guesswork out of datasource management.
- Modern
- Uses Swift's
Diffable Data Sources
,Compositional Layouts
,Generics
andModern Concurrency
- Uses Swift's
- Fully Tested
- I have tested it thoroughly, so you don’t have to.
Define the data model for ItemType
. Must conform to Hashable
protocol.
import DDSViewModels
public struct DummyItem: Hashable {
let text: String
private let creationDate: Date
public init(text: String) {
self.text = text
self.creationDate = Date()
}
public var formattedDate: String {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .medium
return formatter.string(from: creationDate)
}
}
Create the model for your apps sections that implements DiffableSection
.
import DDSViewModels
struct Section: DiffableSection {
public var items: [Item]
public var id = UUID()
public var title: String
init(title: String, items: [Item] = []) {
self.title = title
self.items = items
}
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
public static func == (lhs: Section, rhs: Section) -> Bool {
lhs.id == rhs.id
}
}
Add sections to your heart’s content in an extension on your custom Section
object. Make sure to conform to Hashable
.
extension Section: Hashable {
public static var allSections: [Section] = [
Section(title: "Section1"),
Section(title: "Section2"),
]
public static func returnSections() -> [Section] {
return self.allSections
}
}
import DDSViewModels
final class TableViewCell: UITableViewCell {
let dateLabel = UILabel()
}
Extend your ItemType, implementing Providing
.
extension TableViewCell: Providing {
public typealias Provided = Item
public func provide(_ item: Item) {
self.textLabel?.text = item.text
self.dateLabel.text = item.formattedDate
}
}
import DDSViewModels
final class TableViewModel: UITableDDSViewModel<Section, TableViewCell> {
init(tableView: UITableView) {
super.init(tableView: tableView, cellReuseIdentifier: "TableViewCell")
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let item = diffableDataSource?.itemIdentifier(for: indexPath) else { return }
print(item)
// DO SOMETHING HERE...
}
}
import DDSViewModels
final class TableViewController: UIViewController {
lazy var tableView = UITableView()
private var cancellables = [AnyCancellable]()
lazy var viewModel = TableViewModel(tableView: tableView)
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
configureTableView()
}
private func configureTableView() {
tableView.dataSource = viewModel.makeDiffableDataSource()
}
}
- Open
MenuBar
→File
→Swift Packages
→Add Package Dependency...
- Paste the package repository url
https://github.com/jkaunert/DDSViewModels
and hitNext
. - Select the version/target.
import DDSViewModels
where needed.
If you are building your own package simply add a new dependency:
dependencies: [
.package(url: "https://github.com/jkaunert/DDSViewModels", from: "1.0.0")
]
Your contributions are always appreciated. There are many ways how you help with the project:
- Write additional documentation.
- Implement a new feature.
- Fix a bug.
- Help to maintain by answering to the questions (if any) that other folks have.
Overall guidelies are:
- Fork the project repository. This creates a copy of the project on your account that you can modify without affecting the original project.
- Clone the forked repository to your local machine using a Git client like Git or GitHub Desktop.
- Create and checkout a new branch with a descriptive name (e.g.,
new-feature-branch
orbugfix-issue-123
). - Make changes to the project’s codebase.
- Commit your changes to your local branch with a clear commit message that explains the changes you’ve made.
git commit -m Implemented new feature
. - Push your changes to your forked repository on GitHub.
git push origin new-feature-branch
. - Create a pull request to the original repository. Open a new pull request to the original project repository. In the pull request, describe the changes you’ve made and why they’re necessary. The project maintainers will review your changes and provide feedback or merge them into the main branch.
The project is available under MIT Licence