Skip to content

Commit

Permalink
Fix maintainVisibleContentPosition for reverse flexDirections
Browse files Browse the repository at this point in the history
Summary:
The existing `maintainVisibleContentPosition` implementation assumes top-to-bottom layout on iOS. It selected the fixed position item as the first child in the scroll content container whose offset was larger than the current offset.

However, for lists that render children in reverse order, e.g., with `flexDirection: 'column-reverse'`, the first child will almost always be chosen as the fixed position item. In these reversed list cases, we need to choose the first item with an offset less than the bottom of the viewport.

## Changelog

[iOS][Fixed] Fixes `maintainVisibleContentPosition` for reverse ordered lists

Differential Revision: D64575696
  • Loading branch information
rozele authored and facebook-github-bot committed Oct 22, 2024
1 parent 8320136 commit d03b78c
Showing 1 changed file with 7 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -941,14 +941,19 @@ - (void)_prepareForMaintainVisibleScrollPosition

BOOL horizontal = _scrollView.contentSize.width > self.frame.size.width;
int minIdx = props.maintainVisibleContentPosition.value().minIndexForVisible;
BOOL reverse = props.isReversedVirtualizedList;
for (NSUInteger ii = minIdx; ii < _contentView.subviews.count; ++ii) {
// Find the first view that is partially or fully visible.
UIView *subview = _contentView.subviews[ii];
BOOL hasNewView = NO;
if (horizontal) {
hasNewView = subview.frame.origin.x + subview.frame.size.width > _scrollView.contentOffset.x;
hasNewView = reverse ? subview.frame.origin.x <
_scrollView.contentOffset.x + _scrollView.bounds.size.width - _scrollView.contentInset.right
: subview.frame.origin.x + subview.frame.size.width > _scrollView.contentOffset.x;
} else {
hasNewView = subview.frame.origin.y + subview.frame.size.height > _scrollView.contentOffset.y;
hasNewView = reverse ? subview.frame.origin.y <
_scrollView.contentOffset.y + _scrollView.bounds.size.height - _scrollView.contentInset.bottom
: subview.frame.origin.y + subview.frame.size.height > _scrollView.contentOffset.y;
}
if (hasNewView || ii == _contentView.subviews.count - 1) {
_prevFirstVisibleFrame = subview.frame;
Expand Down

0 comments on commit d03b78c

Please sign in to comment.