diff --git a/CHANGELOG.md b/CHANGELOG.md index 3751a2a20..137725629 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ - Add -[ASDisplayNode detailedLayoutDescription] property to aid debugging. [Adlai Holler](https://github.com/Adlai-Holler) [#476](https://github.com/TextureGroup/Texture/pull/476) - Fix an issue that causes calculatedLayoutDidChange being called needlessly. [Huy Nguyen](https://github.com/nguyenhuy) [#490](https://github.com/TextureGroup/Texture/pull/490) - Negate iOS 11 automatic estimated table row heights. [Christian Selig](https://github.com/christianselig) [#485](https://github.com/TextureGroup/Texture/pull/485) -- Rename ASCellNode.viewModel to ASCellNode.nodeViewModel to reduce collisions with subclass properties implemented by clients. [Adlai Holler](https://github.com/Adlai-Holler) [#499](https://github.com/TextureGroup/Texture/pull/499) +- Rename ASCellNode.viewModel to ASCellNode.nodeModel to reduce collisions with subclass properties implemented by clients. [Adlai Holler](https://github.com/Adlai-Holler) [#504](https://github.com/TextureGroup/Texture/pull/504) - [Breaking] Add content offset bridging property to ASTableNode and ASCollectionNode. Deprecate related methods in ASTableView and ASCollectionView [Huy Nguyen](https://github.com/nguyenhuy) [#460](https://github.com/TextureGroup/Texture/pull/460) ##2.3.5 diff --git a/Source/ASCellNode.h b/Source/ASCellNode.h index bcd5b9ccf..2c911f17a 100644 --- a/Source/ASCellNode.h +++ b/Source/ASCellNode.h @@ -123,14 +123,14 @@ typedef NS_ENUM(NSUInteger, ASCellNodeVisibilityEvent) { * * This property may be set off the main thread, but this method will never be invoked concurrently on the */ -@property (atomic, nullable) id nodeViewModel; +@property (atomic, nullable) id nodeModel; /** - * Asks the node whether it can be updated to the given view model. + * Asks the node whether it can be updated to the given node model. * * The default implementation returns YES if the class matches that of the current view-model. */ -- (BOOL)canUpdateToViewModel:(id)viewModel; +- (BOOL)canUpdateToNodeModel:(id)nodeModel; /** * The backing view controller, or @c nil if the node wasn't initialized with backing view controller diff --git a/Source/ASCellNode.mm b/Source/ASCellNode.mm index 6ff4b7d83..400be0796 100644 --- a/Source/ASCellNode.mm +++ b/Source/ASCellNode.mm @@ -170,9 +170,9 @@ - (void)__setHighlightedFromUIKit:(BOOL)highlighted; } } -- (BOOL)canUpdateToViewModel:(id)viewModel +- (BOOL)canUpdateToNodeModel:(id)nodeModel { - return [self.nodeViewModel class] == [viewModel class]; + return [self.nodeModel class] == [nodeModel class]; } - (NSIndexPath *)indexPath diff --git a/Source/ASCollectionNode.h b/Source/ASCollectionNode.h index 0ca893c2d..9ba6fdcee 100644 --- a/Source/ASCollectionNode.h +++ b/Source/ASCollectionNode.h @@ -433,15 +433,15 @@ NS_ASSUME_NONNULL_BEGIN - (nullable __kindof ASCellNode *)nodeForItemAtIndexPath:(NSIndexPath *)indexPath AS_WARN_UNUSED_RESULT; /** - * Retrieves the view-model for the item at the given index path, if any. + * Retrieves the node-model for the item at the given index path, if any. * * @param indexPath The index path of the requested item. * - * @return The view-model for the given item, or @c nil if no item exists at the specified path or no view-model was provided. + * @return The node-model for the given item, or @c nil if no item exists at the specified path or no node-model was provided. * * @warning This API is beta and subject to change. We'll try to provide an easy migration path. */ -- (nullable id)viewModelForItemAtIndexPath:(NSIndexPath *)indexPath AS_WARN_UNUSED_RESULT; +- (nullable id)nodeModelForItemAtIndexPath:(NSIndexPath *)indexPath AS_WARN_UNUSED_RESULT; /** * Retrieve the index path for the item with the given node. @@ -537,7 +537,7 @@ NS_ASSUME_NONNULL_BEGIN * * @return An object that contains all the data for this item. */ -- (nullable id)collectionNode:(ASCollectionNode *)collectionNode viewModelForItemAtIndexPath:(NSIndexPath *)indexPath; +- (nullable id)collectionNode:(ASCollectionNode *)collectionNode nodeModelForItemAtIndexPath:(NSIndexPath *)indexPath; /** * Similar to -collectionNode:nodeForItemAtIndexPath: diff --git a/Source/ASCollectionNode.mm b/Source/ASCollectionNode.mm index b867a0ea9..994e26188 100644 --- a/Source/ASCollectionNode.mm +++ b/Source/ASCollectionNode.mm @@ -624,10 +624,10 @@ - (ASCellNode *)nodeForItemAtIndexPath:(NSIndexPath *)indexPath return [self.dataController.pendingMap elementForItemAtIndexPath:indexPath].node; } -- (id)viewModelForItemAtIndexPath:(NSIndexPath *)indexPath +- (id)nodeModelForItemAtIndexPath:(NSIndexPath *)indexPath { [self reloadDataInitiallyIfNeeded]; - return [self.dataController.pendingMap elementForItemAtIndexPath:indexPath].viewModel; + return [self.dataController.pendingMap elementForItemAtIndexPath:indexPath].nodeModel; } - (NSIndexPath *)indexPathForNode:(ASCellNode *)cellNode diff --git a/Source/ASCollectionView.mm b/Source/ASCollectionView.mm index da6eadcdc..83bcc2447 100644 --- a/Source/ASCollectionView.mm +++ b/Source/ASCollectionView.mm @@ -202,7 +202,7 @@ @interface ASCollectionView () )asyncDataSource _asyncDataSourceFlags.collectionNodeNodeForSupplementaryElement = [_asyncDataSource respondsToSelector:@selector(collectionNode:nodeForSupplementaryElementOfKind:atIndexPath:)]; _asyncDataSourceFlags.collectionNodeNodeBlockForSupplementaryElement = [_asyncDataSource respondsToSelector:@selector(collectionNode:nodeBlockForSupplementaryElementOfKind:atIndexPath:)]; _asyncDataSourceFlags.collectionNodeSupplementaryElementKindsInSection = [_asyncDataSource respondsToSelector:@selector(collectionNode:supplementaryElementKindsInSection:)]; - _asyncDataSourceFlags.viewModelForItem = [_asyncDataSource respondsToSelector:@selector(collectionNode:viewModelForItemAtIndexPath:)]; + _asyncDataSourceFlags.nodeModelForItem = [_asyncDataSource respondsToSelector:@selector(collectionNode:nodeModelForItemAtIndexPath:)]; _asyncDataSourceFlags.interop = [_asyncDataSource conformsToProtocol:@protocol(ASCollectionDataSourceInterop)]; if (_asyncDataSourceFlags.interop) { @@ -1662,14 +1662,14 @@ - (void)_beginBatchFetching #pragma mark - ASDataControllerSource -- (id)dataController:(ASDataController *)dataController viewModelForItemAtIndexPath:(NSIndexPath *)indexPath +- (id)dataController:(ASDataController *)dataController nodeModelForItemAtIndexPath:(NSIndexPath *)indexPath { - if (!_asyncDataSourceFlags.viewModelForItem) { + if (!_asyncDataSourceFlags.nodeModelForItem) { return nil; } GET_COLLECTIONNODE_OR_RETURN(collectionNode, nil); - return [_asyncDataSource collectionNode:collectionNode viewModelForItemAtIndexPath:indexPath]; + return [_asyncDataSource collectionNode:collectionNode nodeModelForItemAtIndexPath:indexPath]; } - (ASCellNodeBlock)dataController:(ASDataController *)dataController nodeBlockAtIndexPath:(NSIndexPath *)indexPath diff --git a/Source/ASTableView.mm b/Source/ASTableView.mm index 3f230ba40..d0e529c8b 100644 --- a/Source/ASTableView.mm +++ b/Source/ASTableView.mm @@ -1628,7 +1628,7 @@ - (void)rangeController:(ASRangeController *)rangeController updateWithChangeSet #pragma mark - ASDataControllerSource -- (id)dataController:(ASDataController *)dataController viewModelForItemAtIndexPath:(NSIndexPath *)indexPath +- (id)dataController:(ASDataController *)dataController nodeModelForItemAtIndexPath:(NSIndexPath *)indexPath { // Not currently supported for tables. Will be added when the collection API stabilizes. return nil; diff --git a/Source/Details/ASCollectionElement.h b/Source/Details/ASCollectionElement.h index 252d39433..0272aae26 100644 --- a/Source/Details/ASCollectionElement.h +++ b/Source/Details/ASCollectionElement.h @@ -30,9 +30,9 @@ AS_SUBCLASSING_RESTRICTED @property (nonatomic, assign) ASSizeRange constrainedSize; @property (nonatomic, readonly, weak) id owningNode; @property (nonatomic, assign) ASPrimitiveTraitCollection traitCollection; -@property (nonatomic, readonly, nullable) id viewModel; +@property (nonatomic, readonly, nullable) id nodeModel; -- (instancetype)initWithViewModel:(nullable id)viewModel +- (instancetype)initWithNodeModel:(nullable id)nodeModel nodeBlock:(ASCellNodeBlock)nodeBlock supplementaryElementKind:(nullable NSString *)supplementaryElementKind constrainedSize:(ASSizeRange)constrainedSize diff --git a/Source/Details/ASCollectionElement.mm b/Source/Details/ASCollectionElement.mm index 3c16011da..75f75e918 100644 --- a/Source/Details/ASCollectionElement.mm +++ b/Source/Details/ASCollectionElement.mm @@ -31,7 +31,7 @@ @implementation ASCollectionElement { ASCellNode *_node; } -- (instancetype)initWithViewModel:(id)viewModel +- (instancetype)initWithNodeModel:(id)nodeModel nodeBlock:(ASCellNodeBlock)nodeBlock supplementaryElementKind:(NSString *)supplementaryElementKind constrainedSize:(ASSizeRange)constrainedSize @@ -41,7 +41,7 @@ - (instancetype)initWithViewModel:(id)viewModel NSAssert(nodeBlock != nil, @"Node block must not be nil"); self = [super init]; if (self) { - _viewModel = viewModel; + _nodeModel = nodeModel; _nodeBlock = nodeBlock; _supplementaryElementKind = [supplementaryElementKind copy]; _constrainedSize = constrainedSize; @@ -64,7 +64,7 @@ - (ASCellNode *)node node.owningNode = _owningNode; node.collectionElement = self; ASTraitCollectionPropagateDown(node, _traitCollection); - node.nodeViewModel = _viewModel; + node.nodeModel = _nodeModel; _node = node; } return _node; diff --git a/Source/Details/ASDataController.h b/Source/Details/ASDataController.h index 6fd85e89a..82791a685 100644 --- a/Source/Details/ASDataController.h +++ b/Source/Details/ASDataController.h @@ -78,7 +78,7 @@ extern NSString * const ASCollectionInvalidUpdateException; */ - (BOOL)dataController:(ASDataController *)dataController presentedSizeForElement:(ASCollectionElement *)element matchesSize:(CGSize)size; -- (nullable id)dataController:(ASDataController *)dataController viewModelForItemAtIndexPath:(NSIndexPath *)indexPath; +- (nullable id)dataController:(ASDataController *)dataController nodeModelForItemAtIndexPath:(NSIndexPath *)indexPath; @optional diff --git a/Source/Details/ASDataController.mm b/Source/Details/ASDataController.mm index 9e9b9348c..102fca123 100644 --- a/Source/Details/ASDataController.mm +++ b/Source/Details/ASDataController.mm @@ -330,18 +330,18 @@ - (void)_insertElementsIntoMap:(ASMutableElementMap *)map id node = self.node; for (NSIndexPath *indexPath in indexPaths) { ASCellNodeBlock nodeBlock; - id viewModel; + id nodeModel; if (isRowKind) { - viewModel = [dataSource dataController:self viewModelForItemAtIndexPath:indexPath]; + nodeModel = [dataSource dataController:self nodeModelForItemAtIndexPath:indexPath]; // Get the prior element and attempt to update the existing cell node. - if (viewModel != nil && !changeSet.includesReloadData) { + if (nodeModel != nil && !changeSet.includesReloadData) { NSIndexPath *oldIndexPath = [changeSet oldIndexPathForNewIndexPath:indexPath]; if (oldIndexPath != nil) { ASCollectionElement *oldElement = [previousMap elementForItemAtIndexPath:oldIndexPath]; ASCellNode *oldNode = oldElement.node; - if ([oldNode canUpdateToViewModel:viewModel]) { - // Just wrap the node in a block. The collection element will -setViewModel: + if ([oldNode canUpdateToNodeModel:nodeModel]) { + // Just wrap the node in a block. The collection element will -setNodeModel: nodeBlock = ^{ return oldNode; }; @@ -360,7 +360,7 @@ - (void)_insertElementsIntoMap:(ASMutableElementMap *)map constrainedSize = [self constrainedSizeForNodeOfKind:kind atIndexPath:indexPath]; } - ASCollectionElement *element = [[ASCollectionElement alloc] initWithViewModel:viewModel + ASCollectionElement *element = [[ASCollectionElement alloc] initWithNodeModel:nodeModel nodeBlock:nodeBlock supplementaryElementKind:isRowKind ? nil : kind constrainedSize:constrainedSize diff --git a/Tests/ASCollectionModernDataSourceTests.m b/Tests/ASCollectionModernDataSourceTests.m index 5fd096f19..a6daa9782 100644 --- a/Tests/ASCollectionModernDataSourceTests.m +++ b/Tests/ASCollectionModernDataSourceTests.m @@ -24,7 +24,7 @@ @interface ASTestCellNode : ASCellNode @end @interface ASTestSection : NSObject -@property (nonatomic, readonly) NSMutableArray *viewModels; +@property (nonatomic, readonly) NSMutableArray *nodeModels; @end @implementation ASCollectionModernDataSourceTests { @@ -41,10 +41,10 @@ - (void)setUp { // Default is 2 sections: 2 items in first, 1 item in second. sections = [NSMutableArray array]; [sections addObject:[ASTestSection new]]; - [sections[0].viewModels addObject:[NSObject new]]; - [sections[0].viewModels addObject:[NSObject new]]; + [sections[0].nodeModels addObject:[NSObject new]]; + [sections[0].nodeModels addObject:[NSObject new]]; [sections addObject:[ASTestSection new]]; - [sections[1].viewModels addObject:[NSObject new]]; + [sections[1].nodeModels addObject:[NSObject new]]; window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; viewController = [[UIViewController alloc] init]; @@ -60,7 +60,7 @@ - (void)setUp { @selector(numberOfSectionsInCollectionNode:), @selector(collectionNode:numberOfItemsInSection:), @selector(collectionNode:nodeBlockForItemAtIndexPath:), - @selector(collectionNode:viewModelForItemAtIndexPath:), + @selector(collectionNode:nodeModelForItemAtIndexPath:), @selector(collectionNode:contextForSection:), nil]; [mockDataSource setExpectationOrderMatters:YES]; @@ -112,7 +112,7 @@ - (void)testInsertingAnItem skippedReloadIndexPaths:nil]; } -- (void)testReloadingAnItemWithACompatibleViewModel +- (void)testReloadingAnItemWithACompatibleNodeModel { [self loadInitialData]; @@ -120,15 +120,15 @@ - (void)testReloadingAnItemWithACompatibleViewModel NSIndexPath *reloadedPath = [NSIndexPath indexPathForItem:1 inSection:0]; NSIndexPath *deletedPath = [NSIndexPath indexPathForItem:0 inSection:0]; - id viewModel = [NSObject new]; + id nodeModel = [NSObject new]; - // Cell node should get -canUpdateToViewModel: + // Cell node should get -canUpdateToNodeModel: id mockCellNode = [collectionNode nodeForItemAtIndexPath:reloadedPath]; - OCMExpect([mockCellNode canUpdateToViewModel:viewModel]) + OCMExpect([mockCellNode canUpdateToNodeModel:nodeModel]) .andReturn(YES); [self performUpdateReloadingSections:nil - reloadingItems:@{ reloadedPath: viewModel } + reloadingItems:@{ reloadedPath: nodeModel } reloadMappings:@{ reloadedPath: [NSIndexPath indexPathForItem:0 inSection:0] } insertingItems:nil deletingItems:@[ deletedPath ] @@ -168,12 +168,12 @@ - (void)loadInitialData // It reads the contents for each item. for (NSInteger section = 0; section < sections.count; section++) { - NSArray *viewModels = sections[section].viewModels; + NSArray *nodeModels = sections[section].nodeModels; // For each item: - for (NSInteger i = 0; i < viewModels.count; i++) { + for (NSInteger i = 0; i < nodeModels.count; i++) { NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:section]; - [self expectViewModelMethodForItemAtIndexPath:indexPath viewModel:viewModels[i]]; + [self expectNodeModelMethodForItemAtIndexPath:indexPath nodeModel:nodeModels[i]]; [self expectNodeBlockMethodForItemAtIndexPath:indexPath]; } } @@ -201,14 +201,14 @@ - (void)expectDataSourceCountMethods // Note: Skip fast enumeration for readability. for (NSInteger section = 0; section < sections.count; section++) { OCMExpect([mockDataSource collectionNode:collectionNode numberOfItemsInSection:section]) - .andReturn(sections[section].viewModels.count); + .andReturn(sections[section].nodeModels.count); } } -- (void)expectViewModelMethodForItemAtIndexPath:(NSIndexPath *)indexPath viewModel:(id)viewModel +- (void)expectNodeModelMethodForItemAtIndexPath:(NSIndexPath *)indexPath nodeModel:(id)nodeModel { - OCMExpect([mockDataSource collectionNode:collectionNode viewModelForItemAtIndexPath:indexPath]) - .andReturn(viewModel); + OCMExpect([mockDataSource collectionNode:collectionNode nodeModelForItemAtIndexPath:indexPath]) + .andReturn(nodeModel); } - (void)expectContextMethodForSection:(NSInteger)section @@ -240,21 +240,21 @@ - (void)assertCollectionNodeContent for (NSInteger section = 0; section < sections.count; section++) { ASTestSection *sectionObject = sections[section]; - NSArray *viewModels = sectionObject.viewModels; + NSArray *nodeModels = sectionObject.nodeModels; // Assert section object XCTAssertEqualObjects([collectionNode contextForSection:section], sectionObject); // Assert item count - XCTAssertEqual([collectionNode numberOfItemsInSection:section], viewModels.count); - for (NSInteger item = 0; item < viewModels.count; item++) { - // Assert view model + XCTAssertEqual([collectionNode numberOfItemsInSection:section], nodeModels.count); + for (NSInteger item = 0; item < nodeModels.count; item++) { + // Assert node model // Could use pointer equality but the error message is less readable. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; - id viewModel = viewModels[indexPath.item]; - XCTAssertEqualObjects(viewModel, [collectionNode viewModelForItemAtIndexPath:indexPath]); + id nodeModel = nodeModels[indexPath.item]; + XCTAssertEqualObjects(nodeModel, [collectionNode nodeModelForItemAtIndexPath:indexPath]); ASCellNode *node = [collectionNode nodeForItemAtIndexPath:indexPath]; - XCTAssertEqualObjects(node.nodeViewModel, viewModel); + XCTAssertEqualObjects(node.nodeModel, nodeModel); } } } @@ -263,7 +263,7 @@ - (void)assertCollectionNodeContent * Updates the collection node, with expectations and assertions about the call-order and the correctness of the * new data. You should update the data source _before_ calling this method. * - * skippedReloadIndexPaths are the old index paths for nodes that should use -canUpdateToViewModel: instead of being refetched. + * skippedReloadIndexPaths are the old index paths for nodes that should use -canUpdateToNodeModel: instead of being refetched. */ - (void)performUpdateReloadingSections:(NSDictionary *)reloadedSections reloadingItems:(NSDictionary *)reloadedItems @@ -275,7 +275,7 @@ - (void)performUpdateReloadingSections:(NSDictionary *)reloadedS [collectionNode performBatchUpdates:^{ // First update our data source. [reloadedItems enumerateKeysAndObjectsUsingBlock:^(NSIndexPath * _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - sections[key.section].viewModels[key.item] = obj; + sections[key.section].nodeModels[key.item] = obj; }]; [reloadedSections enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { sections[key.integerValue] = obj; @@ -283,13 +283,13 @@ - (void)performUpdateReloadingSections:(NSDictionary *)reloadedS // Deletion paths, sorted descending for (NSIndexPath *indexPath in [deletedItems sortedArrayUsingSelector:@selector(compare:)].reverseObjectEnumerator) { - [sections[indexPath.section].viewModels removeObjectAtIndex:indexPath.item]; + [sections[indexPath.section].nodeModels removeObjectAtIndex:indexPath.item]; } // Insertion paths, sorted ascending. NSArray *insertionsSortedAcending = [insertedItems.allKeys sortedArrayUsingSelector:@selector(compare:)]; for (NSIndexPath *indexPath in insertionsSortedAcending) { - [sections[indexPath.section].viewModels insertObject:insertedItems[indexPath] atIndex:indexPath.item]; + [sections[indexPath.section].nodeModels insertObject:insertedItems[indexPath] atIndex:indexPath.item]; } // Then update the collection node. @@ -314,10 +314,10 @@ - (void)performUpdateReloadingSections:(NSDictionary *)reloadedS // Go through reloaded sections and add all their items into `insertsPlusReloads` [reloadedSectionIndexes enumerateIndexesUsingBlock:^(NSUInteger section, BOOL * _Nonnull stop) { [self expectContextMethodForSection:section]; - NSArray *viewModels = sections[section].viewModels; - for (NSInteger i = 0; i < viewModels.count; i++) { + NSArray *nodeModels = sections[section].nodeModels; + for (NSInteger i = 0; i < nodeModels.count; i++) { NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:section]; - insertsPlusReloads[indexPath] = viewModels[i]; + insertsPlusReloads[indexPath] = nodeModels[i]; } }]; @@ -326,7 +326,7 @@ - (void)performUpdateReloadingSections:(NSDictionary *)reloadedS }]; for (NSIndexPath *indexPath in [insertsPlusReloads.allKeys sortedArrayUsingSelector:@selector(compare:)]) { - [self expectViewModelMethodForItemAtIndexPath:indexPath viewModel:insertsPlusReloads[indexPath]]; + [self expectNodeModelMethodForItemAtIndexPath:indexPath nodeModel:insertsPlusReloads[indexPath]]; NSIndexPath *oldIndexPath = [reloadMappings allKeysForObject:indexPath].firstObject; BOOL isSkippedReload = oldIndexPath && [skippedReloadIndexPaths containsObject:oldIndexPath]; if (!isSkippedReload) { @@ -335,7 +335,7 @@ - (void)performUpdateReloadingSections:(NSDictionary *)reloadedS } } completion:nil]; - // Assert that the counts and view models are all correct now. + // Assert that the counts and node models are all correct now. [self assertCollectionNodeContent]; } @@ -345,9 +345,9 @@ - (void)performUpdateReloadingSections:(NSDictionary *)reloadedS @implementation ASTestCellNode -- (BOOL)canUpdateToViewModel:(id)viewModel +- (BOOL)canUpdateToNodeModel:(id)nodeModel { - // Our tests default to NO for migrating view models. We use OCMExpect to return YES when we specifically want to. + // Our tests default to NO for migrating node models. We use OCMExpect to return YES when we specifically want to. return NO; } @@ -360,7 +360,7 @@ @implementation ASTestSection - (instancetype)init { if (self = [super init]) { - _viewModels = [NSMutableArray array]; + _nodeModels = [NSMutableArray array]; } return self; }