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

[Table / Collection] Trigger new batch fetch after programmatic scrolls, or layout transitions. #1697

Merged

Conversation

nickvelloff
Copy link
Contributor

@nickvelloff nickvelloff commented May 26, 2016

During various layout changes that trigger content size changes, batch fetching needs to recalulate it's number of screens left to scroll before the delegate -collectionView:beginBatchFetchingWithContext: is called.

Just exposes [self _checkForBatchFetching];

UPDATE:
Due to conversations with @appleguy the approach has changed to triggering [self _checkForBatchFetching];internally, at the appropriate times.

After some digging, it appears triggering this on - (NSArray *)visibleNodeIndexPathsForRangeController:(ASRangeController *)rangeController exhibits the least amount of additional calculations, but covers a range of use cases that require a batch fetch re-measurement.

From the code comments:

// We must re-check the batch measurement range when additional cells enter the same visual area
// Use case is - User has 10 items visible, and wants to trigger batch updates at 2x visible screen size, so 20 records need to be fetched. User modifies the collection view (by pinch or other means) and it results in 15 items in the visible space. In order to achieve the 2x batch promise, we now need 30 records. This accounts for that by triggering a remeasurement at the appropriate time.

@ghost ghost added the CLA Signed label May 26, 2016
* @discussion During various layout changes that trigger content size changes, batch fetching needs to recalulate it's number of screens left to scroll before the delegate -collectionView:beginBatchFetchingWithContext: is called. Call when a layout transition is complete, or it will have no effect.
*
*/
- (void)invalidateBatchFetchMeasurements;
Copy link
Contributor

Choose a reason for hiding this comment

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

@nickvelloff Thanks! I see the need for this, but I do not see a need for it to be a public API.

Could you explain? Are you confident it can't be called internally, by something like relayoutItems or similar?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@appleguy I looked really closely to try to find a way to trigger this without exposing it. The problem is, the batch invalidation is purely scroll related, and view re-layout when item size changes is not.
Also having the control to fire this manually gave me the ability to be sure it fired once and only once at the exact end of my interactive ASDisplayNode layout transition.
There are nuances to transitions and their completion, like during a "pinch to zoom" you let go, you must call collectionNode.view.cancelInteractiveTransition() or collectionNode.view.finishInteractiveTransition() typically depending on the transition progress. This means you would only want to fire this in the completion block of startInteractiveTransitionToCollectionViewLayout, which might me really tricky to detect within ASDK.

Happy to try another approach if you have any ideas.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@appleguy All that said I think the correct way to go is ultimately decoupling scroll from this as a hard dependency, and making invalidation/re-measurement of batch trigger in a more generic way. That would solve it without exposing anything. Fear we may be a bit far away from that currently though, from a ASDK priority standpoint (I'm guessing this of course)..

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I guess I am not familiar enough with the use case. Is there no other call the ASCollectionView can intercept from the UICollectionViewDelegate? Or from the layout? There is a proxy so that ASCollectionView is able to listen to absolutely any kind of delegate / datasource call...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Happy to dig in and see if there is another way to trigger this behavior.

Here is my specific use case:

  • x cells displayed in an ASViewController
  • transition to 2nd layout via pinch to zoom
  • fetch is ultimately controlled by number of elements in the view * batch fetch screen count
  • when the number of items displayed on the screen is changed, via a zoom or transition, that must invalidate the calculation, thereby invalidating the data required to fulfill that 3x trailing promise

@nickvelloff
Copy link
Contributor Author

Are you confident it can't be called internally, by something like relayoutItems or similar

ASBatchFetching.m is where the magic happens, and I don't see much there to indicate this is an expensive operation. My goal was to not call it frequently, so I bypassed things like relayoutItems. That might have been a miss on my part.

I'm happy to try another approach.

* @discussion During various layout changes that trigger content size changes, batch fetching needs to recalulate it's number of screens left to scroll before the delegate -collectionView:beginBatchFetchingWithContext: is called. Call when a layout transition is complete, or it will have no effect.
*
*/
- (void)invalidateBatchFetchMeasurements;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's too unclear to users when and why they need to call this, at least because it is still unclear to me :). It may indeed be the only solution, but we have to clarify the cases that it is needed; e.g. what's an example using ASTableView?

I think we should find any possible way for this to be triggered internally even if it means that batch fetching will be re-checked more frequently than absolutely necessary.

@appleguy appleguy changed the title Invalidate batch fetch measurements [WIP] Trigger new batch fetch for collection view after layout transitions Jun 4, 2016
@nickvelloff nickvelloff force-pushed the invalidateBatchFetchMeasurements branch from 16e9c58 to 3897c6f Compare June 17, 2016 10:51
@nickvelloff
Copy link
Contributor Author

@appleguy I think I may have found the appropriate place to trigger this internally. It seems to fire at the appropriate times, and not frequently.

@nickvelloff nickvelloff force-pushed the invalidateBatchFetchMeasurements branch from 3cde6ff to e94a1d1 Compare June 20, 2016 21:06
@nickvelloff nickvelloff force-pushed the invalidateBatchFetchMeasurements branch from e94a1d1 to c129b78 Compare June 20, 2016 21:09
@nickvelloff nickvelloff reopened this Jun 20, 2016
@nickvelloff nickvelloff force-pushed the invalidateBatchFetchMeasurements branch from e58d1e5 to 4f588c8 Compare June 20, 2016 21:17
Expose completed delegate method for ASRangeController
@nickvelloff
Copy link
Contributor Author

OK. This time we are going to add delegate method - (void)didCompleteUpdatesInRangeController:(ASRangeController *)rangeController to ASRangeControllerDelegate

Then trigger at the end of _updateVisibleNodeIndexPaths in ASRangeController
cc @appleguy this is working well for me.

@appleguy appleguy changed the title [WIP] Trigger new batch fetch for collection view after layout transitions [Table / Collection] Trigger new batch fetch after programmatic scrolls, or layout transitions. Jun 22, 2016
@appleguy appleguy merged commit a05d311 into facebookarchive:master Jun 22, 2016
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.

2 participants