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

Majorly Improve automaticallyAdjustsContentOffset #3033

Merged
merged 3 commits into from
Feb 15, 2017

Conversation

Adlai-Holler
Copy link
Contributor

@Adlai-Holler Adlai-Holler commented Feb 15, 2017

  • Only do it for non-animated updates. For animated updates, as I mention in the comments, we can't synchronize with table view's update animation and you see an ugly wave.
    • This is breaking API but we need to do it. No user would ever prefer to see this effect.
  • Switch our tracking system to be much simpler and to account for section headers/footers/etc.
  • Add a unit test for content offset adjusting

Old system:

Update about to start
Save first visible index path
Update inserted rows
Sum up all the nodes' calculatedSize.height
Update deleted rows
Subtract all the nodes' calculatedSize.height
Update about to end
Find the row at the saved index path (!!! may not be correct)
Add the summed-up value to contentOffset.y

New system:

Update about to start
Save the first visible cell node and its y-offset from the top of viewport.
Update about to end
Find the index path for that cell node, and scroll so that its y-offset is what it was before

This removes a ton of logic where we sum up cellNode.calculatedSize and makes sure we handle things like section headers/footers etc.

I also removed some now-unused arguments from ASDataControllerDelegate and ASRangeControllerDelegate.

Resolves #2908

_delegateDidInsertNodes = [_delegate respondsToSelector:@selector(dataController:didInsertNodes:atIndexPaths:withAnimationOptions:)];
_delegateDidDeleteNodes = [_delegate respondsToSelector:@selector(dataController:didDeleteNodes:atIndexPaths:withAnimationOptions:)];
_delegateDidInsertSections = [_delegate respondsToSelector:@selector(dataController:didInsertSections:atIndexSet:withAnimationOptions:)];
_delegateDidDeleteSections = [_delegate respondsToSelector:@selector(dataController:didDeleteSectionsAtIndexSet:withAnimationOptions:)];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All this can be removed because these methods are required i.e. enforced by compiler. Sorry @nguyenhuy if this requires a rebase but it should be simple if so!

Copy link
Contributor

Choose a reason for hiding this comment

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

I also deleted this in #3017. I will rebase with joy if necessary!

Copy link
Contributor

@nguyenhuy nguyenhuy left a comment

Choose a reason for hiding this comment

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

@Adlai-Holler Love it! 1 less thing to handle in #3017. Thanks a ton!

}
}

// We can't do this if we didn't have a top visible row before.
Copy link
Contributor

Choose a reason for hiding this comment

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

It's great that this edge case is handled.

Non-blocking feedback: I'm wondering if we should store 1 or maybe even 2 more nodes? That way we would rarely give up because all of the anchor nodes were gone. The last visible node and the one in the middle are good candidates for this purpose.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call! For the time being, let's leave it as-is to reduce complexity since cases where they delete the anchor row will be somewhat rare, and I have a suspicion that not many people are using this flag.


if (_automaticallyAdjustsContentOffset) {
[self adjustContentOffsetWithNodes:nodes atIndexPaths:indexPaths inserting:YES];
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess these lines are deleted based on the assumption that edits are always done in batches and so offset adjustment can be solely done in -rangeController: didEndUpdatesAnimated:completion:?

I honestly think we should embrace this "always in batches" strategy to the point that there should be only one delegate method -rangeController:didUpdateWithChangeSet:. It will allow us to greatly simplify ASCollectionView and ASTableView. Currently those classes need many internal states to deal with the possibility that updates can be done separately.

_delegateDidInsertNodes = [_delegate respondsToSelector:@selector(dataController:didInsertNodes:atIndexPaths:withAnimationOptions:)];
_delegateDidDeleteNodes = [_delegate respondsToSelector:@selector(dataController:didDeleteNodes:atIndexPaths:withAnimationOptions:)];
_delegateDidInsertSections = [_delegate respondsToSelector:@selector(dataController:didInsertSections:atIndexSet:withAnimationOptions:)];
_delegateDidDeleteSections = [_delegate respondsToSelector:@selector(dataController:didDeleteSectionsAtIndexSet:withAnimationOptions:)];
Copy link
Contributor

Choose a reason for hiding this comment

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

I also deleted this in #3017. I will rebase with joy if necessary!

@Adlai-Holler Adlai-Holler merged commit b616248 into master Feb 15, 2017
@Adlai-Holler Adlai-Holler deleted the AHFixContentOffsetAdjustment branch February 15, 2017 19:57
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