Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

[Umbrella] ASCollectionView -> ASCollectionNode Migration, Separate Index Spaces #2372

Merged
merged 12 commits into from
Oct 15, 2016

Conversation

Adlai-Holler
Copy link
Contributor

@Adlai-Holler Adlai-Holler commented Oct 12, 2016

I've tested this thoroughly with Pinterest using the deprecated API.

Supersedes #2348 .

Methods involving the ASCollectionNode always use data source index space. Methods on the view always use UIKit index space. I may remove nodeForRowAtIndexPath and indexPathForNode from ASTableView to avoid confusion but I'm still thinking about possibly legitimate use cases for them such as interactive reordering and scrollToRowAtIndexPath: or after they call indexPathForCell: for some reason, which they shouldn't do but we can't stop them.

@@ -440,6 +440,7 @@
CC7FD9DF1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9DD1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.m */; };
CC7FD9E11BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7FD9E01BB5F750005CCB2B /* ASPhotosFrameworkImageRequestTests.m */; };
CC7FD9E21BB603FF005CCB2B /* ASPhotosFrameworkImageRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = CC7FD9DC1BB5E962005CCB2B /* ASPhotosFrameworkImageRequest.h */; settings = {ATTRIBUTES = (Public, ); }; };
CC87BB951DA8193C0090E380 /* ASCellNode+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = CC87BB941DA8193C0090E380 /* ASCellNode+Internal.h */; };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file existed before, but wasn't part of the project for some reason.

NSIndexPath *ip = [(ASCollectionNode *)owningNode indexPathForNode:self];
if (ip != nil) {
[result addObject:@{ @"indexPath" : ip }];
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is sort of unrelated and should have been here before. Really helps logging.

/**
* This is a node-based UICollectionViewDataSource.
*/
@protocol ASCollectionDataSource <ASCommonCollectionDataSource>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and ASCollectionDelegate ASTableDataSource and ASTableDelegate) was kept as-is, but moved from the View.h file to the Node.h file.

return [_dataController nodeAtCompletedIndexPath:indexPath];
}

- (NSIndexPath *)convertIndexPathFromCollectionNode:(NSIndexPath *)indexPath waitingIfNeeded:(BOOL)wait
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is private, and only here for backwards-compatibility reasons. Currently the scrollToItemAtIndexPath methods on ASTableView and ASCollectionView take index paths in the data source space, and so for the time being we use this as a shim to maintain that behavior. In the future, after some testing, we'll remove our override on that method, and remove this with it.

- (void)collectionNode:(ASCollectionNode *)collectionNode didEndDisplayingItemWithNode:(ASCellNode *)node;

- (BOOL)collectionNode:(ASCollectionNode *)collectionNode shouldHighlightItemWithNode:(ASCellNode *)node;
- (void)collectionNode:(ASCollectionNode *)collectionNode didHighlightItemWithNode:(ASCellNode *)node;
Copy link
Contributor Author

@Adlai-Holler Adlai-Holler Oct 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a tough question. I could have gone with didSelectItemAtIndexPath etc but since the item/section may have been deleted or reloaded, the argument would have to be nullable which would be really wacky, giving users no information at all. I could filter out cases like that, but there could be legitimate arguments for behaviors like "whenever a header node of X class is showing, the background color of my view should be Y" so filtering out these callbacks would break that. Or if the user happened to select an item just before a section is reloaded, the select would get ignored.

So the user can either 1) build their architecture around nodes directly, and check the node class or 2) call [collectionNode indexPathForNode:node]. The only trouble here is, if they don't nil-check the index path, they'll get {0,0} for item and section, and they may do something even worse! Tough calls… @appleguy @maicki

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I've reversed stance on this. In order to keep things simple, all delegate callbacks except willDisplayRow and didEndDisplayingRow will pass a nonnull NSIndexPath *. In the extremely unlikely case that the user selected an item that is pending deletion/reload, the event won't get sent.

* Boolean parameter that contains the value YES if all of the related animations completed successfully or
* NO if they were interrupted. This parameter may be nil. If supplied, the block is run on the main thread.
*/
- (void)performBatchAnimated:(BOOL)animated updates:(nullable __attribute((noescape)) void (^)())updates completion:(nullable void (^)(BOOL finished))completion;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add back in performBatchUpdates without the animated flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/**
* Asks the data source for the number of items in the given section of the collection node.
*
* @see @c numberOfSectionsInCollectionView:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update

@@ -209,33 +238,19 @@ + (Class)layerClass

- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout
{
return [self _initWithFrame:CGRectZero collectionViewLayout:layout ownedByNode:NO];
return [self _initWithFrame:CGRectZero collectionViewLayout:layout layoutFacilitator:nil];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nit: can this call through into initWithFrame:

@hannahmbanana
Copy link
Contributor

hannahmbanana commented Oct 13, 2016

@Adlai-Holler: Want me to push these example project updates?

  • ASCollectionView
  • ASDKgram
  • ASDKTube
  • CatDealsCollectionView
  • CustomCollectionView
  • HorizontalWithinVerticalScrolling

@Adlai-Holler
Copy link
Contributor Author

@hannahmbanana Sure – feel free to push them onto this branch.

hannahmbanana added a commit that referenced this pull request Oct 14, 2016
These examples were updated to use ASCollectionNode instead of ASCollectionView as part of PR #2372
@hannahmbanana
Copy link
Contributor

@Adlai-Holler: could you review the example file updates?

Adlai Holler and others added 2 commits October 14, 2016 10:01
Beef up our supplementary node support

Make the API way better

Go nuts

Add a unit test for UICollectionView's handling of reloadData inside batch updates

Wrap indexPathForNode: in a cache

Convert index paths in delegate methods

Go back on table view

Put collection view back

Switch up the API

Move most ASCollectionView API to ASCollectionNode

Move most table logic over to ASTableNode

Do the things

More conversion work

Keep on keepin' on

Get table view delegate API done

More porting

Simplify

Clear the delegate

More cleanup

Move more stuff around

Remove pointless file

Re-add some API

Put back more API

Use the right flag
@@ -192,7 +192,7 @@ - (void)tableView:(ASTableView *)tableView willBeginBatchFetchWithContext:(ASBat
- (void)resetAllData
{
[_photoFeed clearFeed];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hannahmbanana Change tableView:willBeginBatchFetchWithContext: above to tableNode:willBeginBatchFetchWithContext:. Is that not showing a deprecation warning? Bummer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also change the other ASTableDelegate methods to tableNode:numberOfRowsInSection: etc.

@@ -92,6 +96,8 @@ - (void)viewDidLoad

- (void)reloadTapped
{
// This method is deprecated because we reccommend using ASCollectionNode instead of ASCollectionView.
// This functionality & example project remains for users who insist on using ASCollectionView.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hannahmbanana Since ASCollectionView outside of the node isn't going to be supported for long, this sample should either be changed majorly or discarded entirely.

@hannahmbanana
Copy link
Contributor

hannahmbanana commented Oct 14, 2016

@Adlai-Holler: There's a bug with ASTableNode / nodeForRowAtIndexPath: not getting called.

ASTableView.mm (line 1389) should be this (the if and elseif: were checking the same flag)
} else if (_asyncDataSourceFlags.tableNodeNodeForRow) {

I'll push the fix when I push the example updates.

@Adlai-Holler
Copy link
Contributor Author

Here we go!

@Adlai-Holler Adlai-Holler merged commit c2ea7cf into master Oct 15, 2016
@Adlai-Holler Adlai-Holler deleted the AHDeprecateTableCollectionView branch October 15, 2016 00:21
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants