触摸 响应者链
事件: 由硬件捕获到用户的一个操作
iOS的事件: 触摸时间, 晃动事件, 远程控制事件
触摸事件: 支持多点触摸, 最多支持11个点, 6s以后的设备支持压感识别
如何捕获用户的触摸事件?
1.用户能够触摸的都是UIView或UIView的子类
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
时间: 2024-12-18 03:04:15