IOS中的响应链

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


 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值