先来解释一下响应者链:
响应者的定义为: iOS上所有能够产生响应事件的对象都是响应者.
响应事件具体分为: 触摸, 晃动, 远程事件
响应者链就是多个响应者的集合, 这些响应者是父子视图的关系.
所有响应者都有一个共同的父类, 叫做: UIResponder
以触摸为例, 响应者链对触摸事件的处理步骤如下:
1. 系统检测到触摸操作, 将消息发送给UIApplication, 开始检测.
2. UIApplication查看发生触摸操作的位置是否还有子视图, 有得话, 继续查找子视图在该位置是否还有子视图, 依次向下, 直到找到最后一个子视图, 将该视图视为该触摸事件的响应者. 完成响应者链的查询过程.
顺序如下: UIApplication -> window -> ViewController -> view -> view 的子视图 -> ......
3. 判断该响应者是否具有处理该触摸事件的能力, 如果有, 那么处理该事件. 如果没有, 则把该视图的父视图作为该触摸事件的响应者, 再判断当前的响应者 (即上一个没有处理事件能力的响应者的父视图) 是否具有处理事件的能力. 如果有, 则处理, 如果没有, 继续按上一个步骤执行. 如果将响应者传递到UIApplication, 并且UIApplication也没有处理该触摸事件的能力, 那么将丢弃该触摸事件.
总结: 响应者链对事件响应者的查询和对事件的处理是两个相反的过程
查询的顺序是: 从UIApplication开始, 逐级向"下"查询, 一直查找到最上面的那个子视图.
处理事件的响应者的查找顺序: 从找到的最上边的子视图, 逐级向"上", 即查找有处理该事件能力的父视图,
假设所有父视图(除了UIApplication), 都没有解决这个事件的能力, 则最后一层的传递则是到UIApplication.
***阻断响应者链 (userInteractionEnabled = NO )
阻断检测查询过程
父视图设置userInteractionEnabled = NO时, 其子视图的响应方法不能得到实现.
UILabel的userInteractionEnabled属性 :
例如: 在UILabel的对象上添加一个UIButton对象, 给UIButton设置一个点击触发事件 buttonAction,
****(注意: 在UILabel对象上添加子视图, 如果该label的背景色不是透明色, 那么将不会显示其上的子视图,.此时虽然该子视图还是在该显示的位置上, 但是由于label的特性, 使得它的子视图不显示出来. 如果不设置label的背景颜色, 则能够显示出子视图.
并且: UILabel的 userInteractionEnabled属性默认为 NO, 即阻断响应者链, 不允许其子视图发生响应事件. 如果想让UILabel对象的子视图具有响应时间的能力, 并且能够响应事件, 那么需要将UILabel对象的userInteractionEnabled属性设置为YES. )
代码如下:
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 200, 100)];
label.text = @"nbigbagn";
//label.backgroundColor = [UIColor blueColor];
//设置label的背景颜色会使其上的子视图不能显示.
[self.window addSubview:label];
[label release];
//设置userInteractionEnabled属性为yes, 是该子视图具备响应事件的能力, 即不阻断响应者链
label.userInteractionEnabled = YES;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(0, 0, 50, 50);
[btn setTitle:@"OK" forState:UIControlStateNormal];
btn.backgroundColor = [UIColor blackColor];
[btn addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
[label addSubview:btn];
[self.window release];
[self.window makeKeyAndVisible];
return YES;
}
-(void)buttonAction:(UIButton *)sender
{
NSLog(@"gfafas");
sender.backgroundColor = [UIColor magentaColor];
}