Skip to content

Instantly share code, notes, and snippets.

@maiyama18
Created August 31, 2022 15:18
Show Gist options
  • Save maiyama18/0e950ca5f17e8cfe760daa8139df345a to your computer and use it in GitHub Desktop.
Save maiyama18/0e950ca5f17e8cfe760daa8139df345a to your computer and use it in GitHub Desktop.
import UIKit
struct Todo: Identifiable {
var id: UUID
var title: String
var done: Bool
}
final class TodoRepository {
private var todos: [Todo] = (1...30).map { i in
Todo(id: UUID(), title: "Todo #\(i)", done: false)
}
var todoIDs: [Todo.ID] { todos.map(\.id) }
func todo(id: Todo.ID) -> Todo? {
todos.first(where: { $0.id == id })
}
}
final class TodoListViewController: UIViewController {
enum Section {
case main
}
private var collectionView: UICollectionView!
private var dataSource: UICollectionViewDiffableDataSource<Section, Todo.ID>!
private var repository: TodoRepository = .init()
override func viewDidLoad() {
super.viewDidLoad()
configureCollectionView()
configureDataSource()
applySnapshot()
}
private func configureCollectionView() {
let layout = UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in
let configuration = UICollectionLayoutListConfiguration(appearance: .plain)
return NSCollectionLayoutSection.list(using: configuration, layoutEnvironment: layoutEnvironment)
}
collectionView = UICollectionView(frame: .null, collectionViewLayout: layout)
view.addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
collectionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
private func configureDataSource() {
let todoCellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Todo> { cell, indexPath, todo in
var configuration = cell.defaultContentConfiguration()
configuration.text = todo.title
cell.contentConfiguration = configuration
cell.accessories = [
.checkmark(displayed: .always, options: .init(isHidden: !todo.done))
]
}
dataSource = UICollectionViewDiffableDataSource(
collectionView: collectionView,
cellProvider: { [weak self] collectionView, indexPath, todoID in
let todo = self?.repository.todo(id: todoID)
return collectionView.dequeueConfiguredReusableCell(using: todoCellRegistration, for: indexPath, item: todo)
}
)
}
private func applySnapshot() {
var snapshot = NSDiffableDataSourceSnapshot<Section, Todo.ID>()
snapshot.appendSections([.main])
snapshot.appendItems(repository.todoIDs, toSection: .main)
dataSource.apply(snapshot, animatingDifferences: true)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment