Edit: Updated to make question more obvious
Edit 2: Made question more accurate to my real-world problem. I\'m actually looking to take a
I was facing the same issue, trying to simulate a tap on a table cell to automate a test for a view controller which handles tapping on a table.
The controller has a private UITapGestureRecognizer created as below:
gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(didRecognizeTapOnTableView)];
The unit test should simulate a touch so that the gestureRecognizer would trigger the action as it was originated from the user interaction.
None of the proposed solutions worked in this scenario, so I solved it decorating UITapGestureRecognizer, faking the exact methods called by the controller. So I added a "performTap" method that call the action in a way the controller itself is unaware of where the action is originated from. This way, I could make a test unit for the controller independent of the gesture recognizer, just of the action triggered.
This is my category, hope it helps someone.
CGPoint mockTappedPoint;
UIView *mockTappedView = nil;
id mockTarget = nil;
SEL mockAction;
@implementation UITapGestureRecognizer (MockedGesture)
-(id)initWithTarget:(id)target action:(SEL)action {
mockTarget = target;
mockAction = action;
return [super initWithTarget:target action:action];
// code above calls UIGestureRecognizer init..., but it doesn't matters
}
-(UIView *)view {
return mockTappedView;
}
-(CGPoint)locationInView:(UIView *)view {
return [view convertPoint:mockTappedPoint fromView:mockTappedView];
}
-(UIGestureRecognizerState)state {
return UIGestureRecognizerStateEnded;
}
-(void)performTapWithView:(UIView *)view andPoint:(CGPoint)point {
mockTappedView = view;
mockTappedPoint = point;
[mockTarget performSelector:mockAction];
}
@end