Problem:
I have a UIView that has a UITableView as a subview. The UIView has a UITapGestureRecognizer configured.
My Problem is that taps on the table are consumed by the UIView's gesture recognizer. The result is the table view never gets to see taps.
How can I either make the recognizer fail when a point is within the table's frame OR make the table the default consumer of the tap.
I have tried (as the code examples show) a number of methods pointInside:withEvent, hitTest:withEvent but can't quite figure out how to do it.
Here is code representing the problem: Controller:
#import <UIKit/UIKit.h>
#import "ABCDTableView.h"
@interface ABCDFirstView : UIView
@property (nonatomic,strong) ABCDTableView *tableView;
@end
#import "ABCDFirstView.h"
@implementation ABCDFirstView
@synthesize tableView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self awakeFromNib];
}
return self;
}
- (void)awakeFromNib
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(viewTouch:)];
[self addGestureRecognizer:tap];
}
- (void)viewTouch:(UIGestureRecognizer *)gesture {
NSLog(@"view touched");
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (CGRectContainsPoint(self.tableView.bounds, point)) {
NSLog(@"point in table point as well as view");
return NO;
}
else if (CGRectContainsPoint(self.bounds, point)) {
NSLog(@"point only in view");
return YES;
}
NSLog(@"point not in view");
return NO;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *view = [super hitTest:point withEvent:event];
NSLog(@"view hittest res: %@",view);
return view;
}
@end
TableView
#import <UIKit/UIKit.h>
@interface ABCDTableView : UITableView
<UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) NSArray *list;
@end
#import "ABCDTableView.h"
@implementation ABCDTableView
@synthesize list;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self awakeFromNib];
}
return self;
}
- (void)awakeFromNib
{
self.delegate = self;
self.dataSource = self;
// create table list
self.list = [[NSArray alloc]
initWithObjects: @"one",@"two",@"three",@"four",@"five",
@"six", @"seven", @"eight", @"nine", @"ten", nil];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.list count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = @"cell";
UITableViewCell *cell = [self dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.textLabel.text = [self.list objectAtIndex:[indexPath row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"row selected");
}
@end
View
#import <UIKit/UIKit.h>
#import "ABCDTableView.h"
@interface ABCDFirstView : UIView
@property (nonatomic,strong) ABCDTableView *tableView;
@end
#import "ABCDFirstView.h"
@implementation ABCDFirstView
@synthesize tableView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self awakeFromNib];
}
return self;
}
- (void)awakeFromNib
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(viewTouch:)];
[self addGestureRecognizer:tap];
}
- (void)viewTouch:(UIGestureRecognizer *)gesture {
NSLog(@"view touched");
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (CGRectContainsPoint(self.tableView.bounds, point)) {
NSLog(@"point in table point as well as view");
return NO;
}
else if (CGRectContainsPoint(self.bounds, point)) {
NSLog(@"point only in view");
return YES;
}
NSLog(@"point not in view");
return NO;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *view = [super hitTest:point withEvent:event];
NSLog(@"view hittest res: %@",view);
return view;
}
@end