事件处理
触摸事件、手势、响应者链、运行循环。
(一)触摸事件
(1)在iOS中的事件可以分为三个类型,触摸事件,加速计事件(摇一摇,呵呵~),远程控制事件(耳机控制音量)。
(2)触摸事件:
1.响应者对象:只要继承了UIResponder的对象就可以处理事件,称为响应者对象。UIApplication,UIViewController,UIView都继承UIResponder,所以都可以处理响应事件。
2.UIResponder:
- (nullable UIResponder*)nextResponder;
// (能够)成为第一响应者
- (BOOL)canBecomeFirstResponder; // default is NO - (BOOL)becomeFirstResponder; - (BOOL)canResignFirstResponder; // default is YES - (BOOL)resignFirstResponder; - (BOOL)isFirstResponder;
// 手指触摸 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event; // 手指移动 - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event; // 手指移开 —> 这三个是一个完整的响应事件 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event; // 手指取消 —> 非正常手指移开(突然接电话什么时候会调用) - (void)touchesCancelled:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
*这里所指的手指,都是一根或者多跟手指。touches里面放的都是UITouch对象,放到NSSet数组里面。
*5S以后手机是64位的了。这时候.count NSUInteger什么的就最好用zd%和tu%了。要不切换32位又会警告。
3.UITouch对象
// 触摸时间 @property(nonatomic,readonly) NSTimeInterval timestamp; @property(nonatomic,readonly) UITouchPhase phase; @property(nonatomic,readonly) NSUInteger tapCount; // touch down within a certain point within a certain amount of time @property(nonatomic,readonly) UITouchType type NS_AVAILABLE_IOS(9_0); // majorRadius and majorRadiusTolerance are in points // The majorRadius will be accurate +/- the majorRadiusTolerance @property(nonatomic,readonly) CGFloat majorRadius NS_AVAILABLE_IOS(8_0); @property(nonatomic,readonly) CGFloat majorRadiusTolerance NS_AVAILABLE_IOS(8_0); @property(nullable,nonatomic,readonly,strong) UIWindow *window; @property(nullable,nonatomic,readonly,strong) UIView *view; @property(nullable,nonatomic,readonly,copy) NSArray <UIGestureRecognizer *> *gestureRecognizers NS_AVAILABLE_IOS(3_2); - (CGPoint)locationInView:(nullable UIView *)view; - (CGPoint)previousLocationInView:(nullable UIView *)view;
*tapCount很少用,一般用用于判断双击,双击一般用于放大图片。
*一个手指对应一个UITouch对象。保存着本次手指触摸相关的信息,比如位置,时间,阶段。俩手指就俩UITouch。手指移动时候会更新UITouch对象,手指离开就会销毁UITouch。
(二)单点触摸案例:
1>手指在view上 view跟随 —> 子view touchBegin
2>当手指点击view的时候 view的中心跑到手指的位置 —> 子view touchMoved
3>手指再空白处 view跟随 —> 主view touchMoved
4>手指再空白处 viewX值跟随 —> 主view touchMoved
子view:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 1.单击,子view变成中心 UITouch *touch = touches.anyObject; // 获得现在的点 CGPoint nowPoint = [touch locationInView:self.superview]; self.center = nowPoint; } - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 3.拖拽时候跟着鼠标走 UITouch *touch = touches.anyObject; // 获得当前的点 CGPoint previousPoint = [touch previousLocationInView:self.superview]; // 获得现在的点 CGPoint nowPoint = [touch locationInView:self.superview]; NSLog(@"%@",NSStringFromCGPoint(nowPoint)); NSLog(@"%@",NSStringFromCGPoint(previousPoint)); // 获取x,y偏移量 CGFloat x = nowPoint.x - previousPoint.x; CGFloat y = nowPoint.y - previousPoint.y; self.transform = CGAffineTransformTranslate(self.transform,x , y); } 主view - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 点击外面view时候,橘色view中心变变成点击点 UITouch *touch = touches.anyObject; self.orangeView.center = [touch locationInView:self]; }
(三)多点触摸案例
1.多点触摸默认是不开启的。需要勾选。
2.代码:
// 单击一下随机出来一个颜色的图
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSLog(@"%@",self.imageArray); // 这个是有的,好的. for (UITouch *t in touches) { CGPoint nowPoint = [t locationInView:self.superview]; UIImageView *imgView = [[UIImageView alloc] initWithImage:[self ramdomImage]]; imgView.center = nowPoint; [self addSubview:imgView]; [UIView animateWithDuration:2.0 animations:^{ imgView.alpha = 0; } completion:^(BOOL finished) { [imgView removeFromSuperview]; }]; } } - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { for (UITouch *t in touches) { CGPoint nowPoint = [t locationInView:self.superview]; UIImageView *imgView = [[UIImageView alloc] initWithImage:[self ramdomImage]]; imgView.center = nowPoint; [self addSubview:imgView]; [UIView animateWithDuration:2.0 animations:^{ imgView.alpha = 0; } completion:^(BOOL finished) { [imgView removeFromSuperview]; }]; } } - (UIImage *)ramdomImage { UIImage *image = self.imageArray[arc4random() % self.imageArray.count]; return image; } // 懒加载 - (NSArray *)imageArray { if (_imageArray == nil) { _imageArray = @[[UIImage imageNamed:@"spark_1"],[UIImage imageNamed:@"spark_2"],[UIImage imageNamed:@"spark_3"],[UIImage imageNamed:@"spark_4"],[UIImage imageNamed:@"spark_5"],[UIImage imageNamed:@"spark_6"],]; } return _imageArray; }