Skip to content

Instantly share code, notes, and snippets.

@lucianboboc
Last active May 5, 2019 16:07
Show Gist options
  • Save lucianboboc/ce8ea30688f8c47ad7a51180cfc079a6 to your computer and use it in GitHub Desktop.
Save lucianboboc/ce8ea30688f8c47ad7a51180cfc079a6 to your computer and use it in GitHub Desktop.

Revisions

  1. lucianboboc revised this gist May 1, 2019. 1 changed file with 50 additions and 8 deletions.
    58 changes: 50 additions & 8 deletions pat.swift
    Original file line number Diff line number Diff line change
    @@ -1,19 +1,61 @@
    protocol SomeProtocol {
    class PersonCell: UICollectionViewCell {
    @IBOutlet weak var firstLabel: UILabel!
    @IBOutlet weak var secondLabel: UILabel!
    }

    struct Person {
    let firstName: String
    let lastName: String
    }

    protocol PersonsDatasourceProtocol: class {
    associatedtype Model
    associatedtype Cell: UICollectionViewCell

    func didSelect(model: Model)
    func indexPath(for sender: Cell) -> IndexPath?
    func reloadData()
    func indexPath(for cell: Cell) -> IndexPath?
    func reloadUI()
    }

    class SomeDatasource<Model, Cell: UICollectionViewCell>: UICollectionViewDataSource, UICollectionViewDelegate {
    var delegate: SomeProtocol<Model, Cell>? // PAT not allowed to be used as type
    class PersonsDatasource<Model, Cell: UICollectionViewCell>: UICollectionViewDataSource, UICollectionViewDelegate {

    var models: [Model] = [] // will be loaded from an api
    weak var delegate: PersonsDatasourceProtocol<Model, Cell>? // not possible

    typealias CellConfigurator = (Model, Cell) -> Void
    private let cellConfigurator: CellConfigurator // injected in init, called in cellForItem(at:)
    private let cellConfigurator: CellConfigurator

    init(cellConfigurator: @escaping CellConfigurator) {
    self.cellConfigurator = cellConfigurator
    }

    // datasource and delegate methods
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let model = self.models[indexPath.item]
    delegate?.didSelect(model: model)
    }
    }

    class PersonsViewController: UIViewController, PersonsDatasourceProtocol {
    typealias Model = Person
    typealias Cell = PersonCell

    @IBOutlet weak var collectionView: UICollectionView!

    let datasource = PersonsDatasource<Model, Cell>(cellConfigurator: { model, cell in
    cell.firstLabel.text = model.firstName
    cell.secondLabel.text = model.lastName
    })

    func didSelect(model: Model) {
    // do something with the model ...
    }

    init(reuseIdentifier: String, cellConfigurator: CellConfigurator) { ... }
    func indexPath(for cell: Cell) -> IndexPath? {
    return collectionView.indexPath(for: cell)
    }

    // collection datasource and delegate methods
    func reloadUI() {
    collectionView.reloadData()
    }
    }
  2. lucianboboc revised this gist May 1, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion pat.swift
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    protocol SomeProtocol {
    associatedtype Model
    associatedtype Cell
    associatedtype Cell: UICollectionViewCell

    func didSelect(model: Model)
    func indexPath(for sender: Cell) -> IndexPath?
  3. lucianboboc renamed this gist May 1, 2019. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. lucianboboc created this gist May 1, 2019.
    19 changes: 19 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    protocol SomeProtocol {
    associatedtype Model
    associatedtype Cell

    func didSelect(model: Model)
    func indexPath(for sender: Cell) -> IndexPath?
    func reloadData()
    }

    class SomeDatasource<Model, Cell: UICollectionViewCell>: UICollectionViewDataSource, UICollectionViewDelegate {
    var delegate: SomeProtocol<Model, Cell>? // PAT not allowed to be used as type

    typealias CellConfigurator = (Model, Cell) -> Void
    private let cellConfigurator: CellConfigurator // injected in init, called in cellForItem(at:)

    init(reuseIdentifier: String, cellConfigurator: CellConfigurator) { ... }

    // collection datasource and delegate methods
    }