您的位置:首页 > 产品设计 > UI/UE

IOS学习 UIGestureRecognizer绑定UIView与UIButton之间的堆叠

2015-02-26 14:11 309 查看
- (void)willMoveToWindow:(UIWindow *)newWindow
{

[selfsetFrame:CGRectMake(0,0,100,100)];
if (!_testBtn)
{

_testBtn = [[UIButtonalloc]initWithFrame:CGRectMake(20,20,60,
60)];

[_testBtnsetBackgroundColor:[UIColorredColor]];

[_testBtnaddTarget:selfaction:@selector(buttonBeClicked:)forControlEvents:UIControlEventTouchUpInside];
[selfaddSubview:_testBtn];

UITapGestureRecognizer *doubleclick = [[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(selfViewBeClicked)];
doubleclick.numberOfTapsRequired =1;
doubleclick.cancelsTouchesInView =FALSE;
doubleclick.numberOfTouchesRequired =1 ;

doubleclick.delegate = (id<UIGestureRecognizerDelegate>)self;
[selfaddGestureRecognizer:doubleclick];
}

}

- (void)buttonBeClicked:(id)sender
{

NSLog(@"ButtonClick");
}

- (void)selfViewBeClicked
{

NSLog(@"SelfViewClick");
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
BOOL isInView = [superpointInside:pointwithEvent:event];
if (isInView)
{

NSLog(@"pointInView");
}
else
{

NSLog(@"pointOutView");
}
return isInView;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

NSLog(@"touchesBegan");
[supertouchesBegan:toucheswithEvent:event];
}

// 询问delegate是否允许手势接收者接收一个touch对象
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch
*)touch
{

NSLog(@"UIGestureRecognizer - FliterTouch");

return
YES;
}

// 询问一个手势接收者是否应该开始解释执行一个触摸接收事件
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{

NSLog(@"UIGestureRecognizer - FliterAction");

return
YES;
}

实验1:点击View
打出的Log是:

2015-02-26 14:14:54.701[b]xxxx[21638:110325] pointInView[/b]
2015-02-26 14:14:54.702[b]xxxx[21638:110325] pointInView[/b]
2015-02-26 14:14:54.702[b]xxxx[21638:110325] UIGestureRecognizer - FliterTouch[/b]
2015-02-26 14:14:54.703[b]xxxx[21638:110325] touchesBegan[/b]
2015-02-26 14:14:54.806[b]xxxx[21638:110325] UIGestureRecognizer - FliterAction[/b]
2015-02-26 14:14:54.807 xxxx[21638:110325] SelfViewClick
如果FliterTouch返回NO则[b]touchesBegan之后的不走。(touchesBegan会走)[/b]
如果[b]FliterAction返回NO则SelfViewClick不走,只是绑定的响应函数不走。

[/b]

实验2:点击Button
打出的Log是:

2015-02-26 14:16:33.573[b]xxxx[21638:110325] pointInView[/b]
2015-02-26 14:16:33.574[b]xxxx[21638:110325] pointInView[/b]
2015-02-26 14:16:33.574[b]xxxx[21638:110325] UIGestureRecognizer - FliterTouch[/b]
2015-02-26 14:16:33.668[b]xxxx[21638:110325] UIGestureRecognizer - FliterAction[/b]
2015-02-26 14:16:33.669[b]xxxx[21638:110325] SelfViewClick[/b]
2015-02-26 14:16:33.669[b]xxxx[21638:110325] ButtonClick[/b]
FliterTouch和FliterAction返回NO时,控制的和上面规律一样。

FliterTouch为NO时,ButtonClick依然会有(证明结论)

实验3:当doubleclick.cancelsTouchesInView =YES时,点击Button

打出的Log是:

2015-02-26 14:34:17.652[b]xxxx[33318:135136] pointInView[/b]
2015-02-26 14:34:17.652[b]xxxx[33318:135136] pointInView[/b]
2015-02-26 14:34:17.652[b]xxxx[33318:135136] UIGestureRecognizer - FliterTouch[/b]
2015-02-26 14:34:17.755[b]xxxx[33318:135136] ButtonClick[/b]

也就是说当手势的cancelsTouchesInView属性为YES时,button的响应会cancel手势的响应。

实验4:没有Button点击UIView时,superView和subView的TouchBegin:withEvent:都会走。

总结:点击UIView的时候TouchBegin:withEvent:才走,UIGestureRecognizer和UITouch代理之间不会相互影响

-------------------------

更新一下:以上实验是父子之间的关系,子view的nextResponder就是父View(nextResponder只能获取,不能设置)

如果两个UIView是平级的,那上层的不响应下层的也不会接到相应通知。(这里详细说一下上层不响应的事)
1.如果上层 UIView的userInteractionEnabled设置为NO那么下层会响应。
如果[b]-
(
BOOL)pointInside:(CGPoint)point
withEvent:(
UIEvent *)event返回NO那么下层也会响应。[/b]

下面说一下父子关系下两个不规则形状View的响应方案:

1.子View的- (nullable
UIView *)hitTest:(CGPoint)point withEvent:(nullable
UIEvent *)event会被调用只要UIEvent[b]事件发生在[/b]父View上。(无论子View的userInteractionEnabled[b][b]设置为什么[/b][/b])

2.View的userInteractionEnabled[b]设置为No的时候
,View的
[/b]- (BOOL)pointInside:(CGPoint)point
withEvent:(UIEvent *)event不会被调用
当然pointInside是在[b]hitTest之后被调用的(其实就是[b]hitTest调用的)。[/b][/b]


4.父View可以重写

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

{

CGPoint subviewP = [self(父View)
convertPoint:point
toView:self.子View];

return [self.子View
pointInside:subviewP withEvent:event];

}

这样就可以只让子View完成响应,而父View的其他部分不作响应,其他部分的响应会传递到下层,交给下层去响应。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: