触摸 响应者链(UITouch,UIIEvent )

触摸 响应者链

    事件: 由硬件捕获到用户的一个操作

    iOS的事件: 触摸时间, 晃动事件, 远程控制事件

    触摸事件: 支持多点触摸, 最多支持11个点, 6s以后的设备支持压感识别

    如何捕获用户的触摸事件?

    1.用户能够触摸的都是UIViewUIView的子类

    2.创建一个UIView的子类

    3.重写UIView的几个方法

和触摸相关的方法

一次触摸包含: 一次开始, 一次结束, 多次移动

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"开始触摸");
    随机位置
   self.center = CGPointMake(arc4random() % 176 + 100, arc4random() % 468 + 100);    
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    NSLog(@"触摸移动");
   self.transform = CGAffineTransformRotate(self.transform, M_PI_4);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"结束触摸");
   
    变大
    bounds修改, center不变, 以中点扩大或缩小
    center修改, bounds不变
    CGRect rect = self.bounds;
    rect.size.width *= 1.1;
    rect.size.height *= 1.1;
    self.bounds = rect;
       
    旋转
    参数1: 原本视图的变形参数
    参数2: 改变的弧度
    self.transform = CGAffineTransformRotate(self.transform, M_PI_4);
    
}
当触摸时, 出现异常情况(比如来电话), 会阻断触摸的执行, 就是调用能触摸取消这个方法
触摸取消这个方法多用于异常情况
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"取消触摸");
}
@end
main.m
   TouchView *touchView = [[TouchView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
    touchView.center = self.view.center;
    touchView.backgroundColor = [UIColor colorWithRed:0.916 green:0.713 blue:1.000 alpha:1.000];
    [self.view addSubview:touchView];
    [touchView release];   
    DragView *dragView = [[DragView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    dragView.backgroundColor = [UIColor cyanColor];
    [self.view addSubview:dragView];
    [dragView release];
DragView.m
#import "DragView.h"
@interface DragView () {
    CGPoint startPoint;
}
@end

@implementation DragView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
   
    touches: 存放触摸点的集合, 集合的元素类型UITouch
        NSLog(@"%@", touches);
    UITouch: 触摸类, 用于存放触摸点的信息(视图, 位置, 窗口, 点击次数,  点击状态), 继承于NSObject
    UITouch *touch =  [touches anyObject];
    点击次数
    NSLog(@"%lu", touch.tapCount);
    时间戳(距离系统开机的秒数)
    NSLog(@"%.lf", touch.timestamp);
    触摸点在某个视图上的位置
    CGPoint startPonit = [touch locationInView:self.superview];
    NSLog(@"%@", NSStringFromCGPoint(startPonit));
    触摸状态: 开始, 移动, 停止, 结束, 取消
    NSLog(@"%ld", touch.phase);
    触摸的压感
     NSLog(@"%.2lf", touch.maximumPossibleForce);
    event: 事件
    UIEvent, 事件类, 继承于NSObject, 存储事件相关信息
    NSLog(@"%@", event);
    事件类型
    NSLog(@"%ld", event.type);
    获取某个触摸点
    UITouch *touch = [touches anyObject];
    给定坐标系, 获取触摸点的位置
    startPoint = [touch locationInView:self.superview];
    NSLog(@"startPoint: %@", NSStringFromCGPoint(startPoint));
    
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint endPoint = [touch locationInView:self.superview];
    NSLog(@"endPoint: %@",NSStringFromCGPoint(endPoint));
    //随鼠标移动
    CGPoint point = self.center;
    point.x += endPoint.x - startPoint.x;
    point.y += endPoint.y - startPoint.y;
    self.center = point;
    
    startPoint = endPoint;
    
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  }

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    
}
@end

 响应者链: 多个响应者组成

    UIResponder, 响应者类

    查找触摸了哪个响应者(范围从大到小)

    1.UIApplication, 应用类

    2.window

    3.UIViewController

    4.view

    5.view的子视图

    : 查找的过程组装响应者链

     处理触摸事件(范围从小到大)

    第一个能够处理响应事件者, 叫第一响应者

RootViewController.m

#import "RootViewController.h"
#import "TouchView.h"
#import "DragView.h"
@interface RootViewController ()<UITextFieldDelegate> {
    UITextField *textField;
    UITextField *passwordField;
}
@end
@implementation RootViewController
- (void)viewDidLoad {
   textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 375 - 200, 40)];
    textField.borderStyle = UITextBorderStyleRoundedRect;
    textField.placeholder = @" 请输入用户名";
    textField.returnKeyType = UIReturnKeyNext;
    textField.delegate = self;
    [self.view addSubview:textField];
    [textField release];
    
    passwordField = [[UITextField alloc] initWithFrame:CGRectMake(100, 160, 375 - 200, 40)];
    passwordField.borderStyle = UITextBorderStyleRoundedRect;
    passwordField.placeholder = @" 请输入密码";
    passwordField.returnKeyType = UIReturnKeyDone;
    passwordField.delegate = self;
    [self.view addSubview:passwordField];
    [passwordField release];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    button.frame = CGRectMake(140, 220, 375 - 280, 40);
    button.titleLabel.font = [UIFont systemFontOfSize:20];
    button.backgroundColor = [UIColor colorWithRed:0.233 green:1.000 blue:0.059 alpha:1.000];
    [button setTitle:@"按钮" forState:UIControlStateNormal];
    [button setTintColor:[UIColor whiteColor]];
    [self.view addSubview:button];
    [button addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];
    
    让textField成为第一响应者
    [textField becomeFirstResponder];
    
    UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(100, 300, 100, 100)];
    bgView.backgroundColor = [UIColor cyanColor];
    
    userInteractionEnabled, 是否开启用户交互, 如果设置为NO, 阻断响应者链的执行
    Bug: 超出父视图范围是无法被点击的
    
    将userInteractionEnabled默认为NO的类
    1.UILabel
    2.UIImageView
    bgView.userInteractionEnabled = NO;
    [self.view addSubview:bgView];
    [bgView release];
    
    UITextField *textField2 = [[UITextField alloc] initWithFrame:CGRectMake(10, 50, 80, 40)];
    textField2.borderStyle = UITextBorderStyleRoundedRect;
    [bgView addSubview:textField2];
    [textField2 release]; 
}

- (void)press {
    NSLog(@"press");
    让textField注销第一响应者
    [textField resignFirstResponder];
    [passwordField resignFirstResponder];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField1 {
    if (textField1 == passwordField) {
        [passwordField resignFirstResponder];
    } else {
    [passwordField becomeFirstResponder];
    }
    return YES;
}
@end

                                                        2015-10-20 20:20:37

 

The one who wants to wear a crown must bear the weight!
原文地址:https://www.cnblogs.com/OrangesChen/p/4895892.html