diff --git a/Sources/DataSources/ASCollectionNode+Rx/ASCollectionSectionedDataSource.swift b/Sources/DataSources/ASCollectionNode+Rx/ASCollectionSectionedDataSource.swift index 462e08c..a293fc2 100644 --- a/Sources/DataSources/ASCollectionNode+Rx/ASCollectionSectionedDataSource.swift +++ b/Sources/DataSources/ASCollectionNode+Rx/ASCollectionSectionedDataSource.swift @@ -18,10 +18,24 @@ open class ASCollectionSectionedDataSource: NSObject, ASCol public typealias Section = S public typealias ConfigureCell = (ASCollectionSectionedDataSource, ASCollectionNode, IndexPath, I) -> ASCellNode + public typealias ConfigureCellBlock = (ASCollectionSectionedDataSource, ASCollectionNode, IndexPath, I) -> ASCellNodeBlock public typealias ConfigureSupplementaryView = (ASCollectionSectionedDataSource, ASCollectionNode, String, IndexPath) -> ASCellNode + public typealias ConfigureSupplementaryViewBlock = (ASCollectionSectionedDataSource, ASCollectionNode, String, IndexPath) -> ASCellNodeBlock public typealias MoveItem = (ASCollectionSectionedDataSource, _ sourceIndexPath: IndexPath, _ destinationIndexPath:IndexPath) -> Void public typealias CanMoveItemAtIndexPath = (ASCollectionSectionedDataSource, IndexPath) -> Bool + fileprivate static func configureCellNotSet(dataSource: ASCollectionSectionedDataSource, node: ASCollectionNode, indexPath: IndexPath, model: I) -> ASCellNode { + return ASCollectionDataSourceNotSet().collectionNode(node, nodeForItemAt: indexPath) + } + + fileprivate static func configureCellBlockNotSet(dataSource: ASCollectionSectionedDataSource, node: ASCollectionNode, indexPath: IndexPath, model: I) -> ASCellNodeBlock { + return { dataSource.collectionNode(node, nodeForItemAt: indexPath) } + } + + fileprivate static func configureSupplementaryViewBlockNotSet(dataSource: ASCollectionSectionedDataSource, node: ASCollectionNode, nodeForSupplementaryElementOfKind kind: String, indexPath: IndexPath) -> ASCellNodeBlock { + return { dataSource.collectionNode(node, nodeForSupplementaryElementOfKind: kind, at: indexPath) } + } + public init( configureCell: @escaping ConfigureCell, configureSupplementaryView: ConfigureSupplementaryView? = nil, @@ -29,7 +43,51 @@ open class ASCollectionSectionedDataSource: NSObject, ASCol canMoveItemAtIndexPath: @escaping CanMoveItemAtIndexPath = { _, _ in false } ) { self.configureCell = configureCell + self.configureCellBlock = ASCollectionSectionedDataSource.configureCellBlockNotSet + self.configureSupplementaryView = configureSupplementaryView + self.configureSupplementaryViewBlock = ASCollectionSectionedDataSource.configureSupplementaryViewBlockNotSet + self.moveItem = moveItem + self.canMoveItemAtIndexPath = canMoveItemAtIndexPath + } + + public init( + configureCellBlock: @escaping ConfigureCellBlock, + configureSupplementaryView: ConfigureSupplementaryView? = nil, + moveItem: @escaping MoveItem = { _, _, _ in () }, + canMoveItemAtIndexPath: @escaping CanMoveItemAtIndexPath = { _, _ in false } + ) { + self.configureCell = ASCollectionSectionedDataSource.configureCellNotSet + self.configureCellBlock = configureCellBlock self.configureSupplementaryView = configureSupplementaryView + self.configureSupplementaryViewBlock = ASCollectionSectionedDataSource.configureSupplementaryViewBlockNotSet + self.moveItem = moveItem + self.canMoveItemAtIndexPath = canMoveItemAtIndexPath + } + + public init( + configureCell: @escaping ConfigureCell, + configureSupplementaryViewBlock: ConfigureSupplementaryViewBlock? = nil, + moveItem: @escaping MoveItem = { _, _, _ in () }, + canMoveItemAtIndexPath: @escaping CanMoveItemAtIndexPath = { _, _ in false } + ) { + self.configureCell = configureCell + self.configureCellBlock = ASCollectionSectionedDataSource.configureCellBlockNotSet + self.configureSupplementaryView = nil + self.configureSupplementaryViewBlock = configureSupplementaryViewBlock + self.moveItem = moveItem + self.canMoveItemAtIndexPath = canMoveItemAtIndexPath + } + + public init( + configureCellBlock: @escaping ConfigureCellBlock, + configureSupplementaryViewBlock: ConfigureSupplementaryViewBlock? = nil, + moveItem: @escaping MoveItem = { _, _, _ in () }, + canMoveItemAtIndexPath: @escaping CanMoveItemAtIndexPath = { _, _ in false } + ) { + self.configureCell = ASCollectionSectionedDataSource.configureCellNotSet + self.configureCellBlock = configureCellBlock + self.configureSupplementaryView = nil + self.configureSupplementaryViewBlock = configureSupplementaryViewBlock self.moveItem = moveItem self.canMoveItemAtIndexPath = canMoveItemAtIndexPath } @@ -92,10 +150,34 @@ open class ASCollectionSectionedDataSource: NSObject, ASCol } } + open var configureCellBlock: ConfigureCellBlock { + didSet { + #if DEBUG + ensureNotMutatedAfterBinding() + #endif + } + } + open var configureSupplementaryView: ConfigureSupplementaryView? { didSet { #if DEBUG ensureNotMutatedAfterBinding() + + if self.configureSupplementaryViewBlock != nil { + print("[WARNING][RxASDataSources] `configureSupplementaryView` is always over written by `configureSupplementaryViewBlock`.") + } + #endif + } + } + + open var configureSupplementaryViewBlock: ConfigureSupplementaryViewBlock? { + didSet { + #if DEBUG + ensureNotMutatedAfterBinding() + + if self.configureSupplementaryView != nil { + print("[WARNING][RxASDataSources] `configureSupplementaryViewBlock` always over write `configureSupplementaryView`.") + } #endif } } @@ -107,6 +189,7 @@ open class ASCollectionSectionedDataSource: NSObject, ASCol #endif } } + open var canMoveItemAtIndexPath: CanMoveItemAtIndexPath { didSet { #if DEBUG @@ -131,6 +214,12 @@ open class ASCollectionSectionedDataSource: NSObject, ASCol return configureCell(self, collectionNode, indexPath, self[indexPath]) } + open func collectionNode(_ collectionNode: ASCollectionNode, nodeBlockForItemAt indexPath: IndexPath) -> ASCellNodeBlock { + precondition(indexPath.item < _sectionModels[indexPath.section].items.count) + + return configureCellBlock(self, collectionNode, indexPath, self[indexPath]) + } + open func collectionNode(_ collectionNode: ASCollectionNode, nodeForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> ASCellNode { guard let cell = configureSupplementaryView?(self, collectionNode, kind, indexPath) else { fatalError("configureSupplementaryView was not set") @@ -138,6 +227,14 @@ open class ASCollectionSectionedDataSource: NSObject, ASCol return cell } + open func collectionNode(_ collectionNode: ASCollectionNode, nodeBlockForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> ASCellNodeBlock { + guard let cell = configureSupplementaryViewBlock?(self, collectionNode, kind, indexPath) else { + fatalError("configureSUpplementaryViewBlock was not set") + } + + return cell + } + open func collectionNode(_ collectionNode: ASCollectionNode, canMoveItemAt indexPath: IndexPath) -> Bool { return canMoveItemAtIndexPath(self, indexPath) } diff --git a/Sources/DataSources/RxProxies/RxASCollectionDelegateProxy.swift b/Sources/DataSources/RxProxies/RxASCollectionDelegateProxy.swift index 4313785..5d025f8 100644 --- a/Sources/DataSources/RxProxies/RxASCollectionDelegateProxy.swift +++ b/Sources/DataSources/RxProxies/RxASCollectionDelegateProxy.swift @@ -121,6 +121,16 @@ public extension Reactive where Base: ASCollectionNode { return ControlEvent(events: source) } + + /// Reactive wrapper for `delegate` message `collectionNode(_:willBeginBatchFetchWith:)` + var willBeginBatchFetch: ControlEvent { + let source: Observable = self.delegate.methodInvoked(#selector(ASCollectionDelegate.collectionNode(_:willBeginBatchFetchWith:))) + .map { a in + return try castOrThrow(ASBatchContext.self, a[1]) + } + + return ControlEvent(events: source) + } /// Reactive wrapper for `delegate` message `collectionNode(_:didSelectItemAtIndexPath:)`. /// diff --git a/Sources/DataSources/RxProxies/RxASTableDelegateProxy.swift b/Sources/DataSources/RxProxies/RxASTableDelegateProxy.swift index ee9c3d7..01a4b76 100644 --- a/Sources/DataSources/RxProxies/RxASTableDelegateProxy.swift +++ b/Sources/DataSources/RxProxies/RxASTableDelegateProxy.swift @@ -128,6 +128,18 @@ public extension Reactive where Base: ASTableNode { return ControlEvent(events: source) } + + /** + Reactive wrapper for `delegate` message `tableNode:willBeginBatchFetchWith` + */ + var willBeginBatchFetch: ControlEvent { + let source: Observable = self.delegate.methodInvoked(#selector(ASTableDelegate.tableNode(_:willBeginBatchFetchWith:))) + .map { a in + return try castOrThrow(ASBatchContext.self, a[1]) + } + + return ControlEvent(events: source) + } /** Reactive wrapper for `delegate` message `tableNode:didSelectRowAtIndexPath:`.