Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hit point when ASCollectionNode inverted set to true #1781

Merged
Merged
10 changes: 7 additions & 3 deletions Source/Details/_ASCollectionViewCell.mm
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ - (void)layoutSubviews

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
ASCellNode *node = self.node;
UIView *nodeView = node.view;

/**
* The documentation for hitTest:withEvent: on an UIView explicitly states the fact that:
* it ignores view objects that are hidden, that have disabled user interactions, or have an
Expand All @@ -106,12 +109,13 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
* superclass hitTest:withEvent: implementation. If this returns a valid value we can go on with
* checking the node as it's expected to not be in one of these states.
*/
if (![super hitTest:self.bounds.origin withEvent:event]) {
CGPoint originPointOnView = [self convertPoint:nodeView.bounds.origin fromView:nodeView];
if (![super hitTest:originPointOnView withEvent:event]) {
return nil;
}

CGPoint pointOnNode = [self.node.view convertPoint:point fromView:self];
return [self.node hitTest:pointOnNode withEvent:event];
CGPoint pointOnNode = [node.view convertPoint:point fromView:self];
return [node hitTest:pointOnNode withEvent:event];
}

- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event
Expand Down
25 changes: 25 additions & 0 deletions Tests/ASCollectionViewTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,31 @@ - (void)testThatCollectionNodeConformsToExpectedProtocols
XCTAssert([node conformsToProtocol:@protocol(ASRangeControllerUpdateRangeProtocol)]);
}

/**
* Test that hit tests are correct when the collection node is inverted.
*/
- (void)testInvertedCollectionViewHitTest
{
ASCollectionViewTestController *testController = [[ASCollectionViewTestController alloc] initWithNibName:nil bundle:nil];
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window setRootViewController:testController];
[window makeKeyAndVisible];

testController.collectionNode.inverted = true;
[testController.collectionNode reloadData];
[testController.collectionNode waitUntilAllUpdatesAreProcessed];
[testController.collectionView layoutIfNeeded];

NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
UICollectionViewCell *cell = [testController.collectionView cellForItemAtIndexPath:indexPath];
ASDisplayNode *node = [testController.collectionNode nodeForItemAtIndexPath:indexPath];

CGPoint testPointInCollectionView = CGPointMake(CGRectGetMidX(cell.frame), CGRectGetMidY(cell.frame));
UIView *hitTestView = [testController.collectionView hitTest:testPointInCollectionView withEvent:nil];

XCTAssertEqualObjects(hitTestView, node.view, @"Expected node's view to be the result of the hit test.");
}

#pragma mark - Update Validations

#define updateValidationTestPrologue \
Expand Down