I'm trying to create an overlay view that monitors for touches and then disappears, but also forwards touch events to whatever is underneath the view.
My test app has a view with a button inside. I add the overlay view as another subview (sibling to the button, essentially), which takes up the entire screen.
For both solutions I tried, the overlay keeps state to determine how it responds to a touch. When a touchesBegan event is received, the overlay will stop responding to hitTest or pointInside until it receives a touchesCancelled or touchesEnded.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if(_respondToTouch)
{
NSLog(@"Responding to hit test");
return [super hitTest:point withEvent:event];
}
NSLog(@"Ignoring hit test");
return nil;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if(_respondToTouch)
{
NSLog(@"Responding to point inside");
return [super pointInside:point withEvent:event];
}
NSLog(@"Ignoring point inside");
return NO;
}
For my first approach, I tried re-issuing the event:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(!_respondToTouch)
{
NSLog(@"Ignoring touches began");
return;
}
NSLog(@"Responding to touches began");
_respondToTouch = NO;
[[UIApplication sharedApplication] sendEvent:event];
}
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches cancelled");
_respondToTouch = YES;
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches ended");
_respondToTouch = YES;
}
However, the button didn't respond to the re-issued event.
My second approach was to use hitTest to discover the view (my button) underneath the overlay, and then send a touchesXXX message directly to it:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches began");
_respondToTouch = NO;
UITouch* touch = [touches anyObject];
_touchDelegate = [[UIApplication sharedApplication].keyWindow hitTest:[touch locationInView:self.superview] withEvent:event];
CGPoint locationInView = [touch locationInView:_touchDelegate];
NSLog(@"Sending touch %@ to view %@. location in view = %f, %f", touch, _touchDelegate, locationInView.x, locationInView.y);
[_touchDelegate touchesBegan:touches withEvent:event];
}
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches cancelled");
[_touchDelegate touchesCancelled:touches withEvent:event];
_respondToTouch = YES;
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches ended");
[_touchDelegate touchesEnded:touches withEvent:event];
_respondToTouch = YES;
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches moved");
[_touchDelegate touchesMoved:touches withEvent:event];
}
It finds the button (according to the logs), but the button doesn't react at all when I invoke touchesXXX on it.
I'm not sure what else to try since the button won't respond to a direct invocation of touchesBegan =/