diff --git a/CHANGELOG.md b/CHANGELOG.md index 05ab8a9..c2c0d71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## UNRELEASED + +* Removed strict `NibReusable` protocol conforming in `register` functions. + You can now make `Reusable` cell, and `NibLoadable` subclass. + [@nekrich](https://github.com/nekrich) + [#37](https://github.com/AliSoftware/Reusable/pull/37) + ## 3.0.0 * Converted library and Demo project to Swift 3. diff --git a/Example/ReusableDemo/CollectionViewCells/CollectionHeaderView.swift b/Example/ReusableDemo/CollectionViewCells/CollectionHeaderView.swift index 2c64d37..2251cff 100644 --- a/Example/ReusableDemo/CollectionViewCells/CollectionHeaderView.swift +++ b/Example/ReusableDemo/CollectionViewCells/CollectionHeaderView.swift @@ -17,8 +17,8 @@ import Reusable * and it uses the CollectionView recycling mechanism) => it is `Reusable` * * That's why it's annotated with the `NibOwnerLoadable` protocol, - * Which in fact is just a convenience protocol that combines - * both `NibLoadable` + `Reusable` protocols. + * Which in fact is just a convenience typealias that combines + * `NibLoadable` & `Reusable` protocols. */ final class CollectionHeaderView: UICollectionReusableView, NibReusable { @IBOutlet private weak var titleLabel: UILabel! { diff --git a/Example/ReusableDemo/CollectionViewCells/MyStoryboardTextSquareCell.swift b/Example/ReusableDemo/CollectionViewCells/MyStoryboardTextSquareCell.swift index f9dd1fb..eb22356 100644 --- a/Example/ReusableDemo/CollectionViewCells/MyStoryboardTextSquareCell.swift +++ b/Example/ReusableDemo/CollectionViewCells/MyStoryboardTextSquareCell.swift @@ -10,8 +10,8 @@ import UIKit import Reusable /** - * This one can be either NibReusable or just Reusable it doesn't really matter, - * as we will never have to explicitly call collectionView.register(…) to register it: + * This one can be either `NibReusable` or just `Reusable` it doesn't really matter, + * as we will never have to explicitly call `collectionView.register(…)` to register it: * The `Main.storyboard` already auto-registers its cells without the need for additional code * * The only difference in marking a view `NibReusable` vs. `Reusable` is the way diff --git a/Example/ReusableDemo/CollectionViewCells/MyXIBIndexSquaceCell.swift b/Example/ReusableDemo/CollectionViewCells/MyXIBIndexSquaceCell.swift index da8f1e8..67fd79e 100644 --- a/Example/ReusableDemo/CollectionViewCells/MyXIBIndexSquaceCell.swift +++ b/Example/ReusableDemo/CollectionViewCells/MyXIBIndexSquaceCell.swift @@ -17,8 +17,8 @@ import Reusable * and it uses the CollectionView recycling mechanism) => it is `Reusable` * * That's why it's annotated with the `NibOwnerLoadable` protocol, - * Which in fact is just a convenience protocol that combines - * both `NibLoadable` + `Reusable` protocols. + * Which in fact is just a typealias that combines + * `NibLoadable` & `Reusable` protocols. */ final class MyXIBIndexSquaceCell: UICollectionViewCell, NibReusable { @IBOutlet private weak var sectionLabel: UILabel! diff --git a/Example/ReusableDemo/TableViewCells/MyStoryBoardIndexPathCell.swift b/Example/ReusableDemo/TableViewCells/MyStoryBoardIndexPathCell.swift index a10058d..9df965d 100644 --- a/Example/ReusableDemo/TableViewCells/MyStoryBoardIndexPathCell.swift +++ b/Example/ReusableDemo/TableViewCells/MyStoryBoardIndexPathCell.swift @@ -9,8 +9,8 @@ import UIKit import Reusable -// This one can be either NibReusable or just Reusable it doesn't matter actually -// As we will never have to explicitly call tableView.register(…) to register it: +// This one can be either `NibReusable` or just `Reusable` it doesn't matter actually +// As we will never have to explicitly call `tableView.register(…)` to register it: // The Main.storyboard already auto-registers its cells without the need for additional code final class MyStoryBoardIndexPathCell: UITableViewCell, Reusable { diff --git a/Example/ReusableDemo/TableViewCells/MyXIBInfoCell.swift b/Example/ReusableDemo/TableViewCells/MyXIBInfoCell.swift index ae7c55a..68187d2 100644 --- a/Example/ReusableDemo/TableViewCells/MyXIBInfoCell.swift +++ b/Example/ReusableDemo/TableViewCells/MyXIBInfoCell.swift @@ -16,9 +16,9 @@ import Reusable * It is also reusable and has a `reuseIdentifier` (as it's a TableViewCell * and it uses the TableView recycling mechanism) => it is `Reusable` * - * That's why it's annotated with the `NibReusable` protocol, - * Which in fact is just a convenience protocol that combines - * both `NibLoadable` + `Reusable` protocols. + * That's why it's annotated with the `NibReusable` typealias, + * Which in fact is just a convenience typealias that combines + * `NibLoadable` & `Reusable` protocols. */ final class MyXIBInfoCell: UITableViewCell, NibReusable { diff --git a/Example/ReusableDemo/TableViewCells/MyXIBTextCell.swift b/Example/ReusableDemo/TableViewCells/MyXIBTextCell.swift index 6ef031e..a9bfd69 100644 --- a/Example/ReusableDemo/TableViewCells/MyXIBTextCell.swift +++ b/Example/ReusableDemo/TableViewCells/MyXIBTextCell.swift @@ -16,9 +16,9 @@ import Reusable * It is also reusable and has a `reuseIdentifier` (as it's a TableViewCell * and it uses the TableView recycling mechanism) => it is `Reusable` * - * That's why it's annotated with the `NibReusable` protocol, - * Which in fact is just a convenience protocol that combines - * both `NibLoadable` + `Reusable` protocols. + * That's why it's annotated with the `NibReusable` typealias, + * Which in fact is just a convenience typealias that combines + * `NibLoadable` & `Reusable` protocols. */ final class MyXIBTextCell: UITableViewCell, NibReusable { diff --git a/README.md b/README.md index 24cfb39..47576bd 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This concept, called a [Mixin](http://alisoftware.github.io/swift/protocol/2015/ ## 1. Declare your cells to conform to `Reusable` or `NibReusable` * Use the `Reusable` protocol if they don't depend on a NIB (this will use `registerClass(…)` to register the cell) -* Use the `NibReusable` protocol if they use a `XIB` file for their content (this will use `registerNib(…)` to register the cell) +* Use the `NibReusable` typealias if they use a `XIB` file for their content (this will use `registerNib(…)` to register the cell) ```swift final class CustomCell: UITableViewCell, Reusable { /* And that's it! */ } @@ -55,6 +55,7 @@ final class CustomCell: UITableViewCell, Reusable { /* And that's it! */ } > > * For cells embedded in a Storyboard's tableView, either one of those two protocols will work (as you won't register the cell them manually anyway) > * If you create a XIB-based cell, don't forget to set its _Reuse Identifier_ field in Interface Builder to the same string as the name of the cell class itself. +> * 💡 `NibReusable` is a typealias, so you could still use two protocols conformance `Reusable, NibLoadable` instead of `NibReusable`.
@@ -77,6 +78,9 @@ final class CodeBasedCustomCell: UITableViewCell, Reusable { ```swift final class NibBasedCustomCell: UITableViewCell, NibReusable { +// or +// final class NibBasedCustomCell: UITableViewCell, Reusable, NibLoadable { + // Here we provide a nib for this cell class (which, if we don't override the protocol's // default implementation of `nib`, will use a XIB of the same name as the class) @@ -106,7 +110,11 @@ final class CodeBasedCollectionViewCell: UICollectionViewCell, Reusable { // A UICollectionViewCell using a XIB to define it's UI // And that will need to register using that XIB final class NibBasedCollectionViewCell: UICollectionViewCell, NibReusable { +// or +// final class NibBasedCollectionViewCell: UICollectionViewCell, Reusable, NibLoadable { + // The rest of the cell code goes here + } ```
@@ -386,7 +394,7 @@ In some cases you can avoid making your classes `final`, but in general it's a g ## Customize reuseIdentifier, nib, etc for non-conventional uses -The protocols in this pod, like `Reusable`, `NibLoadable`, `NibReusable`, `NibOwnerLoadable`, `StoryboardBased`… are what is usually called [Mixins](http://alisoftware.github.io/swift/protocol/2015/11/08/mixins-over-inheritance/), which basically is a Swift protocol with a default implementation provided for all of its methods. +The protocols in this pod, like `Reusable`, `NibLoadable`, `NibOwnerLoadable`, `StoryboardBased`, `NibReusable`… are what is usually called [Mixins](http://alisoftware.github.io/swift/protocol/2015/11/08/mixins-over-inheritance/), which basically is a Swift protocol with a default implementation provided for all of its methods. The main benefit is that **you don't need to add any code**: just conform to `Reusable`, `NibOwnerLoadable` or any of those protocol and you're ready to go with no additional code to write. diff --git a/Sources/View/Reusable.swift b/Sources/View/Reusable.swift index 06a9cbc..28f8e01 100644 --- a/Sources/View/Reusable.swift +++ b/Sources/View/Reusable.swift @@ -19,9 +19,9 @@ public protocol Reusable: class { } /// Make your `UITableViewCell` and `UICollectionViewCell` subclasses -/// conform to this protocol when they *are* NIB-based +/// conform to this typealias when they *are* NIB-based /// to be able to dequeue them in a type-safe manner -public protocol NibReusable: Reusable, NibLoadable {} +public typealias NibReusable = Reusable & NibLoadable // MARK: - Default implementation diff --git a/Sources/View/UICollectionView+Reusable.swift b/Sources/View/UICollectionView+Reusable.swift index 0ef86bf..a6c50c0 100644 --- a/Sources/View/UICollectionView+Reusable.swift +++ b/Sources/View/UICollectionView+Reusable.swift @@ -12,13 +12,13 @@ import UIKit public extension UICollectionView { /** - Register a NIB-Based `UICollectionViewCell` subclass (conforming to `NibReusable`) + Register a NIB-Based `UICollectionViewCell` subclass (conforming to `Reusable` & `NibLoadable`) - - parameter cellType: the `UICollectionViewCell` (`NibReusable`-conforming) subclass to register + - parameter cellType: the `UICollectionViewCell` (`Reusable` & `NibLoadable`-conforming) subclass to register - seealso: `register(_:,forCellWithReuseIdentifier:)` */ - final func register(cellType: T.Type) where T: NibReusable { + final func register(cellType: T.Type) where T: Reusable & NibLoadable { self.register(cellType.nib, forCellWithReuseIdentifier: cellType.reuseIdentifier) } @@ -57,14 +57,14 @@ public extension UICollectionView { } /** - Register a NIB-Based `UICollectionReusableView` subclass (conforming to `NibReusable`) as a Supplementary View + Register a NIB-Based `UICollectionReusableView` subclass (conforming to `Reusable` & `NibLoadable`) as a Supplementary View - - parameter supplementaryViewType: the `UIView` (`NibReusable`-conforming) subclass to register as Supplementary View + - parameter supplementaryViewType: the `UIView` (`Reusable` & `NibLoadable`-conforming) subclass to register as Supplementary View - parameter elementKind: The kind of supplementary view to create. - seealso: `register(_:,forSupplementaryViewOfKind:,withReuseIdentifier:)` */ - final func register(supplementaryViewType: T.Type, ofKind elementKind: String) where T: NibReusable { + final func register(supplementaryViewType: T.Type, ofKind elementKind: String) where T: Reusable & NibLoadable { self.register(supplementaryViewType.nib, forSupplementaryViewOfKind: elementKind, withReuseIdentifier: supplementaryViewType.reuseIdentifier) } diff --git a/Sources/View/UITableView+Reusable.swift b/Sources/View/UITableView+Reusable.swift index bdf35ca..7ec912f 100644 --- a/Sources/View/UITableView+Reusable.swift +++ b/Sources/View/UITableView+Reusable.swift @@ -12,13 +12,13 @@ import UIKit public extension UITableView { /** - Register a NIB-Based `UITableViewCell` subclass (conforming to `NibReusable`) + Register a NIB-Based `UITableViewCell` subclass (conforming to `Reusable` & `NibLoadable`) - - parameter cellType: the `UITableViewCell` (`NibReusable`-conforming) subclass to register + - parameter cellType: the `UITableViewCell` (`Reusable` & `NibLoadable`-conforming) subclass to register - seealso: `register(_:,forCellReuseIdentifier:)` */ - final func register(cellType: T.Type) where T: NibReusable { + final func register(cellType: T.Type) where T: Reusable & NibLoadable { self.register(cellType.nib, forCellReuseIdentifier: cellType.reuseIdentifier) } @@ -57,13 +57,13 @@ public extension UITableView { } /** - Register a NIB-Based `UITableViewHeaderFooterView` subclass (conforming to `NibReusable`) + Register a NIB-Based `UITableViewHeaderFooterView` subclass (conforming to `Reusable` & `NibLoadable`) - - parameter headerFooterViewType: the `UITableViewHeaderFooterView` (`NibReusable`-conforming) subclass to register + - parameter headerFooterViewType: the `UITableViewHeaderFooterView` (`Reusable` & `NibLoadable`-conforming) subclass to register - seealso: `register(_:,forHeaderFooterViewReuseIdentifier:)` */ - final func register(headerFooterViewType: T.Type) where T: NibReusable { + final func register(headerFooterViewType: T.Type) where T: Reusable & NibLoadable { self.register(headerFooterViewType.nib, forHeaderFooterViewReuseIdentifier: headerFooterViewType.reuseIdentifier) }