Skip to content

Commit

Permalink
♻️ Add internal register/dequeue methods
Browse files Browse the repository at this point in the history
  • Loading branch information
usatie committed Sep 17, 2019
1 parent 0ce1c86 commit 27542fb
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 12 deletions.
6 changes: 3 additions & 3 deletions Sources/Mew/Cells+UIKit/CollectionReusableView+UIKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable {
///
/// - Parameter collectionView: Parent collectionView
static func registerAsCollectionViewHeaderFooterView(on collectionView: UICollectionView, for kind: CollectionViewSupplementaryKind) {
CollectionReusableView<Self>.register(to: collectionView, for: kind)
CollectionReusableView<Self>.internalRegister(to: collectionView, for: kind)
}

/// Dequeue Injectable header/footer instance from collectionView
Expand All @@ -27,7 +27,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable {
/// - parentViewController: ParentViewController that must has collectionView.
/// - Returns: The header/footer instance that added the ViewController.view, and the ViewController have injected dependency, VC hierarchy.
static func dequeueAsCollectionViewHeaderFooterView<V>(from collectionView: UICollectionView, of kind: String, for indexPath: IndexPath, input: Self.Input, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> UICollectionReusableView where V: UIViewController, V: Instantiatable, Self.Environment == V.Environment {
return CollectionReusableView<Self>.dequeued(from: collectionView, of: kind, for: indexPath, input: input, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
return CollectionReusableView<Self>.internalDequeued(from: collectionView, of: kind, for: indexPath, input: input, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
}
}

Expand All @@ -43,7 +43,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable,
/// - parentViewController: ParentViewController that must has collectionView.
/// - Returns: The header/footer instance that added the ViewController.
static func dequeueAsCollectionViewHeaderFooterView<V>(from collectionView: UICollectionView, of kind: String, for indexPath: IndexPath, input: Self.Input, output: ((Self.Output) -> Void)?, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> UICollectionReusableView where V: UIViewController, V: Instantiatable, Self.Environment == V.Environment {
return CollectionReusableView<Self>.dequeued(from: collectionView, of: kind, for: indexPath, input: input, output: output, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
return CollectionReusableView<Self>.internalDequeued(from: collectionView, of: kind, for: indexPath, input: input, output: output, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
}
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/Mew/Cells+UIKit/CollectionViewCell+UIKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable {
///
/// - Parameter collectionView: Parent collectionView
static func registerAsCollectionViewCell(on collectionView: UICollectionView) {
CollectionViewCell<Self>.register(to: collectionView)
CollectionViewCell<Self>.internalRegister(to: collectionView)
}

/// Dequeue Injectable cell instance from collectionView
Expand All @@ -27,7 +27,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable {
/// - parentViewController: ParentViewController that must has collectionView.
/// - Returns: The Cell instance that added the ViewController.view, and the ViewController have injected dependency, VC hierarchy.
static func dequeueAsCollectionViewCell<V>(from collectionView: UICollectionView, for indexPath: IndexPath, input: Self.Input, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> UICollectionViewCell where V: UIViewController, V: Instantiatable, Self.Environment == V.Environment {
return CollectionViewCell<Self>.dequeued(from: collectionView, for: indexPath, input: input, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
return CollectionViewCell<Self>.internalDequeued(from: collectionView, for: indexPath, input: input, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
}
}

Expand All @@ -43,7 +43,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable,
/// - parentViewController: ParentViewController that must has collectionView.
/// - Returns: The Cell instance that added the ViewController.
static func dequeueAsCollectionViewCell<V>(from collectionView: UICollectionView, for indexPath: IndexPath, input: Self.Input, output: ((Self.Output) -> Void)?, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> UICollectionViewCell where V: UIViewController, V: Instantiatable, Self.Environment == V.Environment {
return CollectionViewCell<Self>.dequeued(from: collectionView, for: indexPath, input: input, output: output, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
return CollectionViewCell<Self>.internalDequeued(from: collectionView, for: indexPath, input: input, output: output, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
}
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/Mew/Cells+UIKit/TableViewCell+UIKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable {
///
/// - Parameter tableView: Parent tableView
static func registerAsTableViewCell(on tableView: UITableView) {
TableViewCell<Self>.register(to: tableView)
TableViewCell<Self>.internalRegister(to: tableView)
}

/// Dequeue Injectable cell instance from tableView
Expand All @@ -26,7 +26,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable {
/// - parentViewController: ParentViewController that must has tableView.
/// - Returns: The Cell instance that added the ViewController.view, and the ViewController have injected dependency, VC hierarchy.
static func dequeueAsTableViewCell<V>(from tableView: UITableView, for indexPath: IndexPath, input: Self.Input, parentViewController: V) -> UITableViewCell where V: UIViewController, V: Instantiatable, Self.Environment == V.Environment {
return TableViewCell<Self>.dequeued(from: tableView, for: indexPath, input: input, parentViewController: parentViewController)
return TableViewCell<Self>.internalDequeued(from: tableView, for: indexPath, input: input, parentViewController: parentViewController)
}
}

Expand All @@ -41,7 +41,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable,
/// - parentViewController: ParentViewController that must has tableView.
/// - Returns: The Cell instance that added the ViewController.
static func dequeueAsTableViewCell<V>(from tableView: UITableView, for indexPath: IndexPath, input: Self.Input, output: ((Self.Output) -> Void)?, parentViewController: V) -> UITableViewCell where V: UIViewController, V: Instantiatable, Self.Environment == V.Environment {
return TableViewCell<Self>.dequeued(from: tableView, for: indexPath, input: input, output: output, parentViewController: parentViewController)
return TableViewCell<Self>.internalDequeued(from: tableView, for: indexPath, input: input, output: output, parentViewController: parentViewController)
}
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/Mew/Cells+UIKit/TableViewHeaderFooterView+UIKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable {
///
/// - Parameter tableView: Parent tableView
static func registerAsTableViewHeaderFooterView(on tableView: UITableView) {
TableViewHeaderFooterView<Self>.register(to: tableView)
TableViewHeaderFooterView<Self>.internalRegister(to: tableView)
}

/// Dequeue Injectable header/footer instance from tableView
Expand All @@ -25,7 +25,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable {
/// - parentViewController: ParentViewController that must has tableView.
/// - Returns: The header/footer instance that added the ViewController.view, and the ViewController have injected dependency, VC hierarchy.
static func dequeueAsTableViewHeaderFooterView<V>(from tableView: UITableView, input: Self.Input, parentViewController: V) -> UITableViewHeaderFooterView where V: UIViewController, V: Instantiatable, Self.Environment == V.Environment {
return TableViewHeaderFooterView<Self>.dequeued(from: tableView, input: input, parentViewController: parentViewController)
return TableViewHeaderFooterView<Self>.internalDequeued(from: tableView, input: input, parentViewController: parentViewController)
}
}

Expand All @@ -39,7 +39,7 @@ public extension Instantiatable where Self: UIViewController, Self: Injectable,
/// - parentViewController: ParentViewController that must has tableView.
/// - Returns: The header/footer instance that added the ViewController.
static func dequeueAsTableViewHeaderFooterView<V>(from tableView: UITableView, input: Self.Input, output: ((Self.Output) -> Void)?, parentViewController: V) -> UITableViewHeaderFooterView where V: UIViewController, V: Instantiatable, Self.Environment == V.Environment {
return TableViewHeaderFooterView<Self>.dequeued(from: tableView, input: input, output: output, parentViewController: parentViewController)
return TableViewHeaderFooterView<Self>.internalDequeued(from: tableView, input: input, output: output, parentViewController: parentViewController)
}
}

Expand Down
41 changes: 41 additions & 0 deletions Sources/Mew/Cells/CollectionReusableView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ public extension CollectionReusableView {
/// - Parameter collectionView: Parent collectionView
@available(*, deprecated, message: "Please use YourViewController.register(to:for:) instead")
static func register(to collectionView: UICollectionView, for kind: CollectionViewSupplementaryKind) {
internalRegister(to: collectionView, for: kind)
}
}

internal extension CollectionReusableView {
/// Register dequeueable header/footer class for collectionView
///
/// - Parameter collectionView: Parent collectionView
static func internalRegister(to collectionView: UICollectionView, for kind: CollectionViewSupplementaryKind) {
collectionView.register(CollectionReusableView.self, forSupplementaryViewOfKind: kind.rawValue, withReuseIdentifier: reuseIdentifier)
}
}
Expand All @@ -85,6 +94,21 @@ public extension CollectionReusableView where T: Injectable, T: Instantiatable {
/// - Returns: The header/footer instance that added the ViewController.view, and the ViewController have injected dependency, VC hierarchy.
@available(*, deprecated, message: "Please use YourViewController.dequeueReusableSupplementaryView(from:of:for:input:sizeConstraint:parentViewController:) instead")
static func dequeued<V>(from collectionView: UICollectionView, of kind: String, for indexPath: IndexPath, input: T.Input, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> CollectionReusableView where V: UIViewController, V: Instantiatable, T.Environment == V.Environment {
return internalDequeued(from: collectionView, of: kind, for: indexPath, input: input, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
}
}

internal extension CollectionReusableView where T: Injectable, T: Instantiatable {
/// Dequeue header/footer instance from collectionView
///
/// - Parameters:
/// - collectionView: Parent collectionView that must have registered cell.
/// - indexPath: indexPath for dequeue.
/// - input: The ViewController's input.
/// - sizeConstraint: Requirement maximum size of Cell.
/// - parentViewController: ParentViewController that must has collectionView.
/// - Returns: The header/footer instance that added the ViewController.view, and the ViewController have injected dependency, VC hierarchy.
static func internalDequeued<V>(from collectionView: UICollectionView, of kind: String, for indexPath: IndexPath, input: T.Input, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> CollectionReusableView where V: UIViewController, V: Instantiatable, T.Environment == V.Environment {
// Swift4.1 has bug that `Cast from 'X' to unrelated type 'Y<T>' always fails` if T is class and has protocol condition.
let cell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: CollectionReusableView.reuseIdentifier, for: indexPath) as Any as! CollectionReusableView
if cell.contentViewController == nil {
Expand All @@ -97,6 +121,7 @@ public extension CollectionReusableView where T: Injectable, T: Instantiatable {
}
}


public extension CollectionReusableView where T: Injectable, T: Instantiatable, T: Emittable {
/// Dequeue header/footer instance from collectionView
///
Expand All @@ -110,6 +135,22 @@ public extension CollectionReusableView where T: Injectable, T: Instantiatable,
/// - Returns: The header/footer instance that added the ViewController.
@available(*, deprecated, message: "Please use YourViewController.dequeueReusableSupplementaryView(from:of:for:input:output:sizeConstraint:parentViewController:) instead")
static func dequeued<V>(from collectionView: UICollectionView, of kind: String, for indexPath: IndexPath, input: T.Input, output: ((T.Output) -> Void)?, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> CollectionReusableView where V: UIViewController, V: Instantiatable, T.Environment == V.Environment {
return internalDequeued(from: collectionView, of: kind, for: indexPath, input: input, output: output, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
}
}

internal extension CollectionReusableView where T: Injectable, T: Instantiatable, T: Emittable {
/// Dequeue header/footer instance from collectionView
///
/// - Parameters:
/// - collectionView: Parent collectionView that must have registered cell.
/// - indexPath: indexPath for dequeue.
/// - input: The ViewController's input.
/// - output: Handler for ViewController's output. Start handling when cell init. Don't replace handler when cell reused.
/// - sizeConstraint: Requirement maximum size of Cell.
/// - parentViewController: ParentViewController that must has collectionView.
/// - Returns: The header/footer instance that added the ViewController.
static func internalDequeued<V>(from collectionView: UICollectionView, of kind: String, for indexPath: IndexPath, input: T.Input, output: ((T.Output) -> Void)?, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> CollectionReusableView where V: UIViewController, V: Instantiatable, T.Environment == V.Environment {
// Swift4.1 has bug that `Cast from 'X' to unrelated type 'Y<T>' always fails` if T is class and has protocol condition.
let cell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: CollectionReusableView.reuseIdentifier, for: indexPath) as Any as! CollectionReusableView
if cell.contentViewController == nil {
Expand Down
40 changes: 40 additions & 0 deletions Sources/Mew/Cells/CollectionViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ public extension CollectionViewCell {
/// - Parameter collectionView: Parent collectionView
@available(*, deprecated, message: "Please use YourViewController.register(to:)")
static func register(to collectionView: UICollectionView) {
internalRegister(to: collectionView)
}
}

internal extension CollectionViewCell {
/// Register dequeueable cell class for collectionView
///
/// - Parameter collectionView: Parent collectionView
static func internalRegister(to collectionView: UICollectionView) {
collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
}
Expand All @@ -69,6 +78,21 @@ public extension CollectionViewCell where T: Injectable, T: Instantiatable {
/// - Returns: The Cell instance that added the ViewController.view, and the ViewController have injected dependency, VC hierarchy.
@available(*, deprecated, message: "Please use YourViewController.dequeueReusableSupplementaryView(from:for:input:sizeConstraint:parentViewController:) instead")
static func dequeued<V>(from collectionView: UICollectionView, for indexPath: IndexPath, input: T.Input, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> CollectionViewCell where V: UIViewController, V: Instantiatable, T.Environment == V.Environment {
return internalDequeued(from: collectionView, for: indexPath, input: input, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
}
}

internal extension CollectionViewCell where T: Injectable, T: Instantiatable {
/// Dequeue cell instance from collectionView
///
/// - Parameters:
/// - collectionView: Parent collectionView that must have registered cell.
/// - indexPath: indexPath for dequeue.
/// - input: The ViewController's input.
/// - sizeConstraint: Requirement maximum size of Cell.
/// - parentViewController: ParentViewController that must has collectionView.
/// - Returns: The Cell instance that added the ViewController.view, and the ViewController have injected dependency, VC hierarchy.
static func internalDequeued<V>(from collectionView: UICollectionView, for indexPath: IndexPath, input: T.Input, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> CollectionViewCell where V: UIViewController, V: Instantiatable, T.Environment == V.Environment {
// Swift4.1 has bug that `Cast from 'X' to unrelated type 'Y<T>' always fails` if T is class and has protocol condition.
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.reuseIdentifier, for: indexPath) as Any as! CollectionViewCell
if cell.contentViewController == nil {
Expand All @@ -94,6 +118,22 @@ public extension CollectionViewCell where T: Injectable, T: Instantiatable, T: E
/// - Returns: The Cell instance that added the ViewController.
@available(*, deprecated, message: "Please use YourViewController.dequeueReusableSupplementaryView(from:for:input:output:sizeConstraint:parentViewController:) instead")
static func dequeued<V>(from collectionView: UICollectionView, for indexPath: IndexPath, input: T.Input, output: ((T.Output) -> Void)?, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> CollectionViewCell where V: UIViewController, V: Instantiatable, T.Environment == V.Environment {
return internalDequeued(from: collectionView, for: indexPath, input: input, output: output, sizeConstraint: sizeConstraint, parentViewController: parentViewController)
}
}

internal extension CollectionViewCell where T: Injectable, T: Instantiatable, T: Emittable {
/// Dequeue cell instance from collectionView
///
/// - Parameters:
/// - collectionView: Parent collectionView that must have registered cell.
/// - indexPath: indexPath for dequeue.
/// - input: The ViewController's input.
/// - output: Handler for ViewController's output. Start handling when cell init. Don't replace handler when cell reused.
/// - sizeConstraint: Requirement maximum size of Cell.
/// - parentViewController: ParentViewController that must has collectionView.
/// - Returns: The Cell instance that added the ViewController.
static func internalDequeued<V>(from collectionView: UICollectionView, for indexPath: IndexPath, input: T.Input, output: ((T.Output) -> Void)?, sizeConstraint: SizeConstraint? = nil, parentViewController: V) -> CollectionViewCell where V: UIViewController, V: Instantiatable, T.Environment == V.Environment {
// Swift4.1 has bug that `Cast from 'X' to unrelated type 'Y<T>' always fails` if T is class and has protocol condition.
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.reuseIdentifier, for: indexPath) as Any as! CollectionViewCell
if cell.contentViewController == nil {
Expand Down
Loading

0 comments on commit 27542fb

Please sign in to comment.