ios 获取响应链 ios开发响应链_传递

APP中的响应链之间的关系

正文;

在UIKIT里面,存在触摸对象没有检测到事件的情况下,事件将传递到下一个对象的机制。此机制为响应链,最先接收事件的响应者,我们称为第一响应者。如图展示

ios 获取响应链 ios开发响应链_触摸_02

如上图,被触摸的对象作为第一响应者,首先事件传递给它。第一响应者没有相应的话,接着将事件传递到管理第一响应的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];

    
    
}



效果展示:


ios 获取响应链 ios开发响应链_ios 获取响应链_03


ios 获取响应链 ios开发响应链_UILabel的触发事件_04




如图所示,但我们触摸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的讲解如下:



ios 获取响应链 ios开发响应链_传递_05




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在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)