防止父视图 UIGestureRecongnizer 在 UITableVIew 子视图中执行
Posted
技术标签:
【中文标题】防止父视图 UIGestureRecongnizer 在 UITableVIew 子视图中执行【英文标题】:Preventing parent views UIGestureRecongnizer executing within a UITableVIew subview 【发布时间】:2012-10-10 09:49:05 【问题描述】:问题:
我有一个UIView,它有一个UITableView 作为子视图。 UIView 配置了UITapGestureRecognizer。
我的问题是 UIView 的手势识别器会消耗桌面上的点击。结果是表格视图永远不会看到水龙头。
当一个点在表格的框架内时,如何让识别器失败,或者让表格成为点击的默认使用者。
我已经尝试(如代码示例所示)多种方法pointInside:withEvent、hitTest:withEvent,但不知道该怎么做。
这是代表问题的代码: 控制器:
#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
表格视图
#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
查看
#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
【问题讨论】:
【参考方案1】:使用 UIGestureRecognizerDelegate 方法
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
并检查 touch.view 是否与应该接收手势识别器的视图相同。
【讨论】:
以上是关于防止父视图 UIGestureRecongnizer 在 UITableVIew 子视图中执行的主要内容,如果未能解决你的问题,请参考以下文章
Swift 4:防止UIView的子视图移动到它的父节点之外