forked from ishkawa/DataSourceKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
397 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// | ||
// BindableCell.swift | ||
// DataSourceKit | ||
// | ||
// Created by Yosuke Ishikawa on 2018/09/02. | ||
// Copyright © 2018年 Yosuke Ishikawa. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
public protocol BindableCell { | ||
associatedtype Value | ||
static func makeBinder(value: Value) -> CellBinder | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// CellBinder.swift | ||
// DataSourceKit | ||
// | ||
// Created by Yosuke Ishikawa on 2018/09/02. | ||
// Copyright © 2018年 Yosuke Ishikawa. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
public struct CellBinder { | ||
public let nib: UINib | ||
public let reuseIdentifier: String | ||
|
||
internal let configureCell: (Any) -> Void | ||
|
||
public init<Cell>(cellType: Cell.Type, nib: UINib, reuseIdentifier: String, configureCell: @escaping (Cell) -> Void) { | ||
self.nib = nib | ||
self.reuseIdentifier = reuseIdentifier | ||
self.configureCell = { cell in | ||
guard let cell = cell as? Cell else { | ||
fatalError("Could not cast UICollectionView cell to \(Cell.self)") | ||
} | ||
|
||
configureCell(cell) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// | ||
// CellsDeclarator.swift | ||
// DataSourceKit | ||
// | ||
// Created by Yosuke Ishikawa on 2018/09/02. | ||
// Copyright © 2018 Yosuke Ishikawa. All rights reserved. | ||
// | ||
|
||
public protocol CellsDeclarator { | ||
associatedtype CellDeclaration | ||
func declareCells(_ cell: (CellDeclaration) -> Void) | ||
} | ||
|
||
extension CellsDeclarator { | ||
public var cellDeclarations: [CellDeclaration] { | ||
var declarations = [] as [CellDeclaration] | ||
declareCells { declaration in | ||
declarations.append(declaration) | ||
} | ||
return declarations | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// | ||
// CollectionViewDataSource.swift | ||
// DataSourceKit | ||
// | ||
// Created by Yosuke Ishikawa on 2018/09/02. | ||
// Copyright © 2018年 Yosuke Ishikawa. All rights reserved. | ||
// | ||
|
||
import UIKit | ||
|
||
public class CollectionViewDataSource<CellDeclaration>: NSObject, UICollectionViewDataSource { | ||
public var cellDeclarations = [] as [CellDeclaration] | ||
|
||
private var registeredReuseIdentifiers = [] as [String] | ||
private let binderFromDeclaration: (CellDeclaration) -> CellBinder | ||
|
||
public init(binderFromDeclaration: @escaping (CellDeclaration) -> CellBinder) { | ||
self.binderFromDeclaration = binderFromDeclaration | ||
super.init() | ||
} | ||
|
||
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | ||
return cellDeclarations.count | ||
} | ||
|
||
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { | ||
let cellBinder = binderFromDeclaration(cellDeclarations[indexPath.item]) | ||
if !registeredReuseIdentifiers.contains(cellBinder.reuseIdentifier) { | ||
collectionView.register(cellBinder.nib, forCellWithReuseIdentifier: cellBinder.reuseIdentifier) | ||
registeredReuseIdentifiers.append(cellBinder.reuseIdentifier) | ||
} | ||
|
||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellBinder.reuseIdentifier, for: indexPath) | ||
cellBinder.configureCell(cell) | ||
|
||
return cell | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// | ||
// CollectionViewDataSourceTests.swift | ||
// DataSourceKitTests | ||
// | ||
// Created by Yosuke Ishikawa on 2018/09/02. | ||
// Copyright © 2018年 Yosuke Ishikawa. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import XCTest | ||
import DataSourceKit | ||
|
||
class CollectionViewDataSourceTests: XCTestCase { | ||
enum CellDeclaration { | ||
case a(A) | ||
case b(B) | ||
} | ||
|
||
struct Data: CellsDeclarator { | ||
var a: [A] | ||
var b: [B] | ||
|
||
func declareCells(_ cell: (CellDeclaration) -> Void) { | ||
for a in a { | ||
cell(.a(a)) | ||
} | ||
for b in b { | ||
cell(.b(b)) | ||
} | ||
} | ||
} | ||
|
||
var dataSource: CollectionViewDataSource<CellDeclaration>! | ||
var collectionView: TestCollectionView! | ||
|
||
override func setUp() { | ||
super.setUp() | ||
|
||
dataSource = CollectionViewDataSource<CellDeclaration> { declaration in | ||
switch declaration { | ||
case .a(let a): | ||
return TestCellA.makeBinder(value: a) | ||
case .b(let b): | ||
return TestCellB.makeBinder(value: b) | ||
} | ||
} | ||
|
||
collectionView = TestCollectionView(frame: UIScreen.main.bounds, collectionViewLayout: UICollectionViewFlowLayout()) | ||
collectionView.dataSource = dataSource | ||
} | ||
|
||
func test() { | ||
let data = Data(a: [A(id: 1), A(id: 2)], b: [B(id: 1)]) | ||
dataSource.cellDeclarations = data.cellDeclarations | ||
collectionView.reloadData() | ||
collectionView.layoutIfNeeded() | ||
|
||
XCTAssertEqual(dataSource.collectionView(collectionView, numberOfItemsInSection: 0), 3) | ||
XCTAssertEqual(collectionView.nibRegistrations.map({ $0.reuseIdentifier }), ["TestCellA", "TestCellB"]) | ||
|
||
let verifiers: [(UICollectionViewCell?) -> Void] = [ | ||
{ cell in | ||
let cell = cell as? TestCellA | ||
XCTAssertNotNil(cell) | ||
XCTAssertEqual(cell?.idLabel.text, "1") | ||
}, | ||
{ cell in | ||
let cell = cell as? TestCellA | ||
XCTAssertNotNil(cell) | ||
XCTAssertEqual(cell?.idLabel.text, "2") | ||
}, | ||
{ cell in | ||
let cell = cell as? TestCellB | ||
XCTAssertNotNil(cell) | ||
XCTAssertEqual(cell?.idLabel.text, "1") | ||
}, | ||
] | ||
|
||
for (index, verifier) in verifiers.enumerated() { | ||
let indexPath = IndexPath(item: index, section: 0) | ||
let cell = collectionView.cellForItem(at: indexPath) | ||
verifier(cell) | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.