Permalink
Browse files

Fix tapping to be smarter and try to tap the visible area, not just t…

…he center of a view
  • Loading branch information...
1 parent 0d94702 commit 6136299ec2332db8e1694fc01443ae47599ea19b @efirestone efirestone committed Jun 15, 2011
Showing with 41 additions and 17 deletions.
  1. +3 −0 Additions/UIView-KIFAdditions.h
  2. +28 −15 Additions/UIView-KIFAdditions.m
  3. +10 −2 Classes/KIFTestStep.m
@@ -35,4 +35,7 @@
*/
- (BOOL)isTappableInRect:(CGRect)rect;
+
+- (CGPoint)tappablePointInRect:(CGRect)rect;
+
@end
@@ -263,43 +263,56 @@ - (BOOL)isTappable;
}
- (BOOL)isTappableInRect:(CGRect)rect;
+{
+ CGPoint tappablePoint = [self tappablePointInRect:rect];
+
+ return !isnan(tappablePoint.x);
+}
+
+- (CGPoint)tappablePointInRect:(CGRect)rect;
{
// Start at the top and recurse down
CGRect frame = [self.window convertRect:rect fromView:self];
UIView *hitView = nil;
+ CGPoint tapPoint = CGPointZero;
+
+ // Mid point
+ tapPoint = CGPointCenteredInRect(frame);
+ hitView = [self.window hitTest:tapPoint withEvent:nil];
+ if ([hitView isDescendantOfView:self]) {
+ return [self.window convertPoint:tapPoint toView:self];
+ }
// Top left
- hitView = [self.window hitTest:CGPointMake(frame.origin.x + 1.0f, frame.origin.y + 1.0f) withEvent:nil];
+ tapPoint = CGPointMake(frame.origin.x + 1.0f, frame.origin.y + 1.0f);
+ hitView = [self.window hitTest:tapPoint withEvent:nil];
if ([hitView isDescendantOfView:self]) {
- return YES;
+ return [self.window convertPoint:tapPoint toView:self];
}
// Top right
- hitView = [self.window hitTest:CGPointMake(frame.origin.x + 1.0f + frame.size.width - 1.0f, frame.origin.y + 1.0f) withEvent:nil];
+ tapPoint = CGPointMake(frame.origin.x + 1.0f + frame.size.width - 1.0f, frame.origin.y + 1.0f);
+ hitView = [self.window hitTest:tapPoint withEvent:nil];
if ([hitView isDescendantOfView:self]) {
- return YES;
+ return [self.window convertPoint:tapPoint toView:self];
}
// Bottom left
- hitView = [self.window hitTest:CGPointMake(frame.origin.x + 1.0f, frame.origin.y + frame.size.height - 1.0f) withEvent:nil];
+ tapPoint = CGPointMake(frame.origin.x + 1.0f, frame.origin.y + frame.size.height - 1.0f);
+ hitView = [self.window hitTest:tapPoint withEvent:nil];
if ([hitView isDescendantOfView:self]) {
- return YES;
+ return [self.window convertPoint:tapPoint toView:self];
}
// Bottom right
- hitView = [self.window hitTest:CGPointMake(frame.origin.x + frame.size.width - 1.0f, frame.origin.y + frame.size.height - 1.0f) withEvent:nil];
- if ([hitView isDescendantOfView:self]) {
- return YES;
- }
-
- // Mid point
- hitView = [self.window hitTest:CGPointCenteredInRect(frame) withEvent:nil];
+ tapPoint = CGPointMake(frame.origin.x + frame.size.width - 1.0f, frame.origin.y + frame.size.height - 1.0f);
+ hitView = [self.window hitTest:tapPoint withEvent:nil];
if ([hitView isDescendantOfView:self]) {
- return YES;
+ return [self.window convertPoint:tapPoint toView:self];
}
- return NO;
+ return CGPointMake(NAN, NAN);
}
@end
View
@@ -158,7 +158,11 @@ + (id)stepToTapViewWithAccessibilityLabel:(NSString *)label value:(NSString *)va
}
CGRect elementFrame = [view.window convertRect:element.accessibilityFrame toView:view];
- [view tapAtPoint:CGPointCenteredInRect(elementFrame)];
+ CGPoint tappablePointInElement = [view tappablePointInRect:elementFrame];
+
+ // This is mostly redundant of the test in _accessibilityElementWithLabel:
+ KIFTestCondition(!isnan(tappablePointInElement.x), error, @"The element with accessibility label %@ is not tappable", label);
+ [view tapAtPoint:tappablePointInElement];
// Verify that we successfully selected the view
if (![view canBecomeFirstResponder]) {
@@ -193,7 +197,11 @@ + (id)stepToEnterText:(NSString *)text intoViewWithAccessibilityLabel:(NSString
KIFTestWaitCondition(view, error, @"Cannot find view with accessibility label \"%@\"", label);
CGRect elementFrame = [view.window convertRect:element.accessibilityFrame toView:view];
- [view tapAtPoint:CGPointCenteredInRect(elementFrame)];
+ CGPoint tappablePointInElement = [view tappablePointInRect:elementFrame];
+
+ // This is mostly a redundant of the test in _accessibilityElementWithLabel:
+ KIFTestCondition(!isnan(tappablePointInElement.x), error, @"The element with accessibility label %@ is not tappable", label);
+ [view tapAtPoint:tappablePointInElement];
KIFTestCondition([view isAncestorOfFirstResponder], error, @"Failed to make the view with accessibility label \"%@\" the first responder. First responder is %@", label, [[[UIApplication sharedApplication] keyWindow] firstResponder]);

0 comments on commit 6136299

Please sign in to comment.