Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

detect touch on a view behind another view?

Tags:

objective-c

I have two views

  • the top view has some opaque and some transparent regions
  • the bottom view has some clickable buttons.

The top view is completely covering the bottom view, but since top view has transparent areas, bottom view can still be seen.

BUT, i cannot detect button clicks on the bottom view anymore since topview is blocking it, what should I do?

Is there anyway to let top view pass the touches to bottom view?

like image 790
mkto Avatar asked Aug 02 '11 12:08

mkto


3 Answers

My solution for my own question, hope it helps someone.

In the front view, listen for touchesEnded:withEvent delegate.

When this delegate fires, you knows that a user is touching the front view.

Next you need to check whether the finger position touches special areas in the BOTTOM view.

What to do is:

1) Convert the point to relative to the bottom view:

UITouch *touch = [touches anyObject];
CGPoint touchPointInLowerView = [touch locationInView:self.lowerViewController.view];
BOOL isLowerButtonClicked = [self.lowerViewController isFingerOnYourButton:touchPointInLowerView];
if(isLowerButtonClicked)
{
 // lower button clicked
}

2) In the lower view

- (BOOL) isFingerOnYourButton:(CGPoint)point
{
 return CGRectContainsPoint(self.aButton.frame, point);
}  

voila. In this way, we can detect clicks in bottom view even it is blocked by another interactive view on top.

like image 127
mkto Avatar answered Sep 20 '22 01:09

mkto


Turn off user interaction in the top view that is blocking the view underneath:

topView.userInteractionEnabled = NO;
like image 32
highlycaffeinated Avatar answered Sep 20 '22 01:09

highlycaffeinated


If you don't want the top view (or any of its subviews) to respond to touches at all, you can set the userInteractionEnabled property to NO for that view and be done with it.

Otherwise, your best bet is to override pointInside:withEvent: or hitTest:withEvent: in the top view's class. If the top view and the bottom view are siblings, it should enough to return NO from pointInside:withEvent:; if they are further separated in the view hierarchy, you may have to override hitTest:withEvent: to explicitly return the bottom view for the transparent areas.

like image 25
Anomie Avatar answered Sep 21 '22 01:09

Anomie