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

Commit

Permalink
Fixed sticky header touch handling bug
Browse files Browse the repository at this point in the history
Summary:In order to ensure that the docked sticky header in a ListView receives touches correctly, RCTScrollView has a custom hitTest implementation that checks the sticky headers for touches prior to checking any other views.

There was a bug in this implementation that meant that sticky views would get touch priority even if the touch was outside the bounds of the scrollView. This meant that sticky headers that scrolled off the top of the list would intercept touches intended for views placed above the scrollView.

This diff fixes that bug by checking that the touch is inside the scrollview before checking for sticky header touches. I've also limited the custom hit test logic to just the currently docked header, as the other sticky header views do not require special treatment.

Reviewed By: javache

Differential Revision: D3041236

fb-gh-sync-id: a2a3474dda03d5b51688bd575195a67956184bbe
shipit-source-id: a2a3474dda03d5b51688bd575195a67956184bbe
  • Loading branch information
nicklockwood authored and Facebook Github Bot 1 committed Mar 14, 2016
1 parent 9a8ac9d commit 688bb17
Showing 1 changed file with 12 additions and 16 deletions.
28 changes: 12 additions & 16 deletions React/Views/RCTScrollView.m
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ @interface RCTCustomScrollView : UIScrollView<UIGestureRecognizerDelegate>


@implementation RCTCustomScrollView
{
__weak UIView *_dockedHeaderView;
}

- (instancetype)initWithFrame:(CGRect)frame
{
Expand Down Expand Up @@ -335,6 +338,7 @@ - (void)dockClosestSectionHeader
}
currentHeader.transform = CGAffineTransformMakeTranslation(0, yOffset);
currentHeader.layer.zPosition = ZINDEX_STICKY_HEADER;
_dockedHeaderView = currentHeader;

if (previousHeader) {
// The previous header sits right above the currentHeader's initial position
Expand All @@ -349,22 +353,14 @@ - (void)dockClosestSectionHeader

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
__block UIView *hitView;

NSArray *subviews = [self contentView].reactSubviews;
NSUInteger subviewCount = subviews.count;
[_stickyHeaderIndices enumerateIndexesWithOptions:0 usingBlock:^(NSUInteger idx, BOOL *stop) {
if (idx >= subviewCount) {
*stop = YES;
return;
if (_dockedHeaderView && [self pointInside:point withEvent:event]) {
CGPoint convertedPoint = [_dockedHeaderView convertPoint:point fromView:self];
UIView *hitView = [_dockedHeaderView hitTest:convertedPoint withEvent:event];
if (hitView) {
return hitView;
}
UIView *stickyHeader = subviews[idx];
CGPoint convertedPoint = [stickyHeader convertPoint:point fromView:self];
hitView = [stickyHeader hitTest:convertedPoint withEvent:event];
*stop = (hitView != nil);
}];

return hitView ?: [super hitTest:point withEvent:event];
}
return [super hitTest:point withEvent:event];
}

- (void)setRefreshControl:(RCTRefreshControl *)refreshControl
Expand Down Expand Up @@ -897,7 +893,7 @@ - (void)setOnRefreshStart:(RCTDirectEventBlock)onRefreshStart
_onRefreshStart = [onRefreshStart copy];

if (!_scrollView.refreshControl) {
RCTRefreshControl *refreshControl = [[RCTRefreshControl alloc] init];
RCTRefreshControl *refreshControl = [RCTRefreshControl new];
[refreshControl addTarget:self action:@selector(refreshControlValueChanged) forControlEvents:UIControlEventValueChanged];
_scrollView.refreshControl = refreshControl;
}
Expand Down

0 comments on commit 688bb17

Please sign in to comment.