I am doing an iPad app. How do I send touch events to its superview?
I am adding a view which is always some other activity. On that I am adding scrollview to h
Top voted solution was not fully working for me, it was in fact passing along touches to some parts of the UI but it was messing with my tableView intercepting touch events, what finally did it was overriding hitTest in the view I want to ignore touches (that would be your transparent view) and let the subviews of that view handle them (that would be your button)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
UIView *view = [super hitTest:point withEvent:event];
if (view == self) {
return nil; //avoid delivering touch events to the container view (self)
}
else{
return view; //the subviews will still receive touch events
}
}
#import <UIKit/UIKit.h>
@interface TransperentView : UIView
@end
#import "TransperentView.h"
@implementation TransperentView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
[self addTransperentView];
[self addbutton];
}
return self;
}
-(void)addTransperentView
{
UIView *aView = [[UIView alloc]initWithFrame:[self.superview bounds]];
aView.backgroundColor = [UIColor clearColor];
[self addSubview:aView];
}
-(void)addbutton
{
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setTitle:@"clickMe" forState:UIControlStateNormal];
[aButton addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
[aButton setFrame:CGRectMake(100, 200, 90, 90)];
[self addSubview:aButton];
}
-(void)buttonClicked
{
NSLog(@"button clicked");
}
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
for(UIView *vi in self.subviews)
{
if([vi isKindOfClass:[UIButton class]])
{
return YES;
}
}
return NO;
}
//in main view i have added a button through xib
@interface ViewController : UIViewController
{
IBOutlet UIButton *helloButton;
}
- (IBAction)whenButtonTapped:(id)sender;
@end
#import "ViewController.h"
#import "TransperentView.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
TransperentView *tView = [[TransperentView alloc]initWithFrame:self.view.bounds];
[self.view addSubview:tView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc
{
[helloButton release];
[super dealloc];
}
- (IBAction)whenButtonTapped:(id)sender
{
[helloButton setTitle:@"world" forState:UIControlStateNormal];
}
@end
Set the view's userInteractionEnabled
property to NO
. This lets all touches through to the view behind it.
You can set it in the interface builder/storyboards in the attributes inspector, or in code:
yourView.userInteractionEnabled = NO;
For when you have a transparent view with a button in it:
Make a subclass of that view and override the pointInside
method. The way I do it, is to give the button's frame to the subclass as a property, to check for in the pointInside
method:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
BOOL pointInside = NO;
// Check if the touch is in the button's frame
if (CGRectContainsPoint(_buttonFrame, point)) pointInside = YES;
return pointInside;
}
Hope it helps!