APP中的响应链之间的关系
正文;
在UIKIT里面,存在触摸对象没有检测到事件的情况下,事件将传递到下一个对象的机制。此机制为响应链,最先接收事件的响应者,我们称为第一响应者。如图展示
如上图,被触摸的对象作为第一响应者,首先事件传递给它。第一响应者没有相应的话,接着将事件传递到管理第一响应的UIViewcontroller。如果,还没有相应的话,接着传递给第一响应者的母体View。如果母体还没有相应的话,将事件传递给母体VIew的UIviewcontroller。。。。。。就这样就成为一条响应链。如果,还没有相应的话,该事件将废掉。。。。。
在创建的时候,我们要重写UIlabel的init方法。。。代码如下;
//重写init方法
-(id)init
{
if (self=[super init]) {
//将userInteractionEnabled设置为yes
self.userInteractionEnabled=YES;
//UILabel自动调整
self.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
}
return self;
}
在次,添加了
self.userInteractionEnabled=YES;这是为了开启创建的每一个UILabel的交互功能。。
然后,要将每一个UILabe的触发事件传递到下一个控件,,,代码如下:
<pre name="code" class="objc">-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//检测到标签首先将标签标题输出
NSLog(@"%@",self.text);
//事件直接传递到下一个响应控件
[self.nextResponder touchesBegan:touches withEvent:event];
// UIAlertView*al=[[UIAlertView alloc]initWithTitle:nil message:@"wo is label" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
// [al show];
}
就是使用,UIResponder的nextResponder属性。。。。。
然后我们就要创建3个标签,来验证我们的说法:代码如下:
#import "ViewController.h"
#import "Mylabel.h"
@implementation ViewController
-(void)viewDidLoad{
[super viewDidLoad];
//首先将3个标签中最里面父层标签追加到View里面
Mylabel*li1=[[Mylabel alloc]init];
li1.frame=CGRectInset(self.view.bounds, 40, 20);
li1.text=@"A";
li1.backgroundColor=[UIColor darkGrayColor];
[self.view addSubview:li1];
//将第二个标签追加到第一个标签上】
Mylabel*li2=[[Mylabel alloc]init];
li2.frame=CGRectInset(li1.bounds, 40, 20);
li2.text=@"B";
li2.backgroundColor=[UIColor grayColor];
[li1 addSubview:li2];
//将第3个标签追加到第2个标签上
Mylabel*li3=[[Mylabel alloc]init];
li3.frame=CGRectInset(li2.bounds, 40, 20);
li3.text=@"C";
li3.backgroundColor=[UIColor whiteColor];
[li2 addSubview:li3];
}
然后,我们要考虑到3个标签都没响应的时候,我们将调用一个触发事件,,,,代吗如下:
//任何标签都没相应的话,将调用该方法啊
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UIAlertView*al=[[UIAlertView alloc]initWithTitle:nil message:@"我是一个 UIViewcontroller" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
[al show];
}
效果展示:
如图所示,但我们触摸C的时候,触摸事件依然在传递,画面最终(UIViewcontroller)响应了一个事件。。。重要的是,在输出日志里的顺序是C-B-A,所以,响应联
的顺序是。
标签C-->标签B----》标签C
完整的代码如下:
#import <UIKit/UIKit.h>
@interface Mylabel : UILabel
@end
#import "Mylabel.h"
@implementation Mylabel
//重写init方法
-(id)init
{
if (self=[super init]) {
//将userInteractionEnabled设置为yes
self.userInteractionEnabled=YES;
//UILabel自动调整
self.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//检测到标签首先将标签标题输出
NSLog(@"%@",self.text);
//事件直接传递到下一个响应控件
[self.nextResponder touchesBegan:touches withEvent:event];
// UIAlertView*al=[[UIAlertView alloc]initWithTitle:nil message:@"wo is label" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
// [al show];
}
@end
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
#import "ViewController.h"
#import "Mylabel.h"
@implementation ViewController
-(void)viewDidLoad{
[super viewDidLoad];
//首先将3个标签中最里面父层标签追加到View里面
Mylabel*li1=[[Mylabel alloc]init];
li1.frame=CGRectInset(self.view.bounds, 40, 20);
li1.text=@"A";
li1.backgroundColor=[UIColor darkGrayColor];
[self.view addSubview:li1];
//将第二个标签追加到第一个标签上】
Mylabel*li2=[[Mylabel alloc]init];
li2.frame=CGRectInset(li1.bounds, 40, 20);
li2.text=@"B";
li2.backgroundColor=[UIColor grayColor];
[li1 addSubview:li2];
//将第3个标签追加到第2个标签上
Mylabel*li3=[[Mylabel alloc]init];
li3.frame=CGRectInset(li2.bounds, 40, 20);
li3.text=@"C";
li3.backgroundColor=[UIColor whiteColor];
[li2 addSubview:li3];
}
//任何标签都没相应的话,将调用该方法啊
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UIAlertView*al=[[UIAlertView alloc]initWithTitle:nil message:@"我是一个 UIViewcontroller" delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok", nil];
[al show];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
友情链接:
CGRectInset的讲解如下:
frame和dounds的区别
<p><pre name="code" class="objc">rame和bounds是UIView中的两个属性(property)。
-(CGRect)frame{
returnCGRectMake(self.frame.origin.x,self.frame.origin.y,self.frame.size.width,self.frame.size.height);
}
-(CGRect)bounds{
returnCGRectMake(0,0,self.frame.size.width,self.frame.size.height);
}
frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)
bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)