You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
5.1 KiB

5 years ago
  1. /*********************************************
  2. *
  3. * This code is under the MIT License (MIT)
  4. *
  5. * Copyright (c) 2016 AliSoftware
  6. *
  7. *********************************************/
  8. import UIKit
  9. // MARK: Reusable support for UICollectionView
  10. public extension UICollectionView {
  11. /**
  12. Register a NIB-Based `UICollectionViewCell` subclass (conforming to `Reusable` & `NibLoadable`)
  13. - parameter cellType: the `UICollectionViewCell` (`Reusable` & `NibLoadable`-conforming) subclass to register
  14. - seealso: `register(_:,forCellWithReuseIdentifier:)`
  15. */
  16. final func register<T: UICollectionViewCell>(cellType: T.Type)
  17. where T: Reusable & NibLoadable {
  18. self.register(cellType.nib, forCellWithReuseIdentifier: cellType.reuseIdentifier)
  19. }
  20. /**
  21. Register a Class-Based `UICollectionViewCell` subclass (conforming to `Reusable`)
  22. - parameter cellType: the `UICollectionViewCell` (`Reusable`-conforming) subclass to register
  23. - seealso: `register(_:,forCellWithReuseIdentifier:)`
  24. */
  25. final func register<T: UICollectionViewCell>(cellType: T.Type)
  26. where T: Reusable {
  27. self.register(cellType.self, forCellWithReuseIdentifier: cellType.reuseIdentifier)
  28. }
  29. /**
  30. Returns a reusable `UICollectionViewCell` object for the class inferred by the return-type
  31. - parameter indexPath: The index path specifying the location of the cell.
  32. - parameter cellType: The cell class to dequeue
  33. - returns: A `Reusable`, `UICollectionViewCell` instance
  34. - note: The `cellType` parameter can generally be omitted and infered by the return type,
  35. except when your type is in a variable and cannot be determined at compile time.
  36. - seealso: `dequeueReusableCell(withReuseIdentifier:,for:)`
  37. */
  38. final func dequeueReusableCell<T: UICollectionViewCell>(for indexPath: IndexPath, cellType: T.Type = T.self) -> T
  39. where T: Reusable {
  40. let bareCell = self.dequeueReusableCell(withReuseIdentifier: cellType.reuseIdentifier, for: indexPath)
  41. guard let cell = bareCell as? T else {
  42. fatalError(
  43. "Failed to dequeue a cell with identifier \(cellType.reuseIdentifier) matching type \(cellType.self). "
  44. + "Check that the reuseIdentifier is set properly in your XIB/Storyboard "
  45. + "and that you registered the cell beforehand"
  46. )
  47. }
  48. return cell
  49. }
  50. /**
  51. Register a NIB-Based `UICollectionReusableView` subclass (conforming to `Reusable` & `NibLoadable`)
  52. as a Supplementary View
  53. - parameter supplementaryViewType: the `UIView` (`Reusable` & `NibLoadable`-conforming) subclass
  54. to register as Supplementary View
  55. - parameter elementKind: The kind of supplementary view to create.
  56. - seealso: `register(_:,forSupplementaryViewOfKind:,withReuseIdentifier:)`
  57. */
  58. final func register<T: UICollectionReusableView>(supplementaryViewType: T.Type, ofKind elementKind: String)
  59. where T: Reusable & NibLoadable {
  60. self.register(
  61. supplementaryViewType.nib,
  62. forSupplementaryViewOfKind: elementKind,
  63. withReuseIdentifier: supplementaryViewType.reuseIdentifier
  64. )
  65. }
  66. /**
  67. Register a Class-Based `UICollectionReusableView` subclass (conforming to `Reusable`) as a Supplementary View
  68. - parameter supplementaryViewType: the `UIView` (`Reusable`-conforming) subclass to register as Supplementary View
  69. - parameter elementKind: The kind of supplementary view to create.
  70. - seealso: `register(_:,forSupplementaryViewOfKind:,withReuseIdentifier:)`
  71. */
  72. final func register<T: UICollectionReusableView>(supplementaryViewType: T.Type, ofKind elementKind: String)
  73. where T: Reusable {
  74. self.register(
  75. supplementaryViewType.self,
  76. forSupplementaryViewOfKind: elementKind,
  77. withReuseIdentifier: supplementaryViewType.reuseIdentifier
  78. )
  79. }
  80. /**
  81. Returns a reusable `UICollectionReusableView` object for the class inferred by the return-type
  82. - parameter elementKind: The kind of supplementary view to retrieve.
  83. - parameter indexPath: The index path specifying the location of the cell.
  84. - parameter viewType: The view class to dequeue
  85. - returns: A `Reusable`, `UICollectionReusableView` instance
  86. - note: The `viewType` parameter can generally be omitted and infered by the return type,
  87. except when your type is in a variable and cannot be determined at compile time.
  88. - seealso: `dequeueReusableSupplementaryView(ofKind:,withReuseIdentifier:,for:)`
  89. */
  90. final func dequeueReusableSupplementaryView<T: UICollectionReusableView>
  91. (ofKind elementKind: String, for indexPath: IndexPath, viewType: T.Type = T.self) -> T
  92. where T: Reusable {
  93. let view = self.dequeueReusableSupplementaryView(
  94. ofKind: elementKind,
  95. withReuseIdentifier: viewType.reuseIdentifier,
  96. for: indexPath
  97. )
  98. guard let typedView = view as? T else {
  99. fatalError(
  100. "Failed to dequeue a supplementary view with identifier \(viewType.reuseIdentifier) "
  101. + "matching type \(viewType.self). "
  102. + "Check that the reuseIdentifier is set properly in your XIB/Storyboard "
  103. + "and that you registered the supplementary view beforehand"
  104. )
  105. }
  106. return typedView
  107. }
  108. }