码迷,mamicode.com
首页 > 移动开发 > 详细

iOS中的触摸事件

时间:2015-04-11 20:40:52      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

UIKit 可识别三种类型的输入事件:
  • 触摸事件
  • 运动(加速计)事件
  • 远程控制事件 
UIEvent
iOS 中许多事件对象都是 UIEvent 类的实例,记录时间产生的时刻和类型
UIEvent类时间类型的 enum 常量:
 
typedef NS_ENUM(NSInteger, UIEventType) {
    UIEventTypeTouches,
    UIEventTypeMotion,
    UIEventTypeRemoteControl,
};
 
触摸事件的处理
UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件。
 
1. 一根或者多根手指开始触摸屏幕
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 
2.一根或者多根手指在屏幕上移动(随着手指的移动,会持续调用该方法)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
 
3.一根或者多根手指离开屏幕
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
 
4.触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
 
上述4个方法都有个UIEvent的参数,通过UIEvent可以得到事件的类型和产生时间,以及当前处于活动状态的所有触摸操作。但是,通常会使用UITouch对象而不是UIEvent对象来处理触摸事件
 
当用户触摸屏幕时,系统会创建一个UITouch实例,并将该对象和接触屏幕的那根手指关联。UITouch保存着手指在屏幕上触摸的位置。当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指在屏幕上的当前位置。当手指离开屏幕时,系统会取消相应的UITouch对象
 
UITouch对象还会保存一些其他信息,比如,手指的前一个位置、手指按下屏幕的次数(tapCount, 可以用来判断单击和双击事件)
 
UITouch
获取 touches 的位置
 
- (CGPoint)locationInView:(UIView *)view     
返回一个CGPoint类型的值,表示触摸在view这个视图上的位置,这里返回的位置是针对view的坐标系的。调用时传入的view参数为空的话,返回的时触摸点在整个窗口的位置
 
- (CGPoint)previousLocationInView:(UIView *)view
该方法记录了前一个坐标值,函数返回也是一个CGPoint类型的值, 表示触摸在view这个视图上的位置,这里返回的位置是针对view的坐标系的。调用时传入的view参数为空的话,返回的时触摸点在整个窗口的位置
 
@property(nonatomic, readonly, retain) UIView *view
触摸产生时所处的视图。由于视图可能发生变化,当前视图也不一定时最初的视图
 
@property(nonatomic, readonly, retain) UIWindow *window
触摸产生时所处的窗口。由于窗口可能发生变化,当前所在的窗口不一定是最开始的窗口
 
@property(nonatomic, readonly) CGFloat majorRadius (iOS 8)
touch 的半径,是一个近似值,可根据 majorRadiusTolerance property 来调整得到准确的数值。
 
@property(nonatomic, readonly) CGFloat majorRadiusTolerance (iOS 8)
这个值决定了majorRadius属性中值的准确性。majorRadius加上这个值可以得到最大半径,减去得到最小半径。
 
获取 touch 的属性
 
@property(nonatomic, readonly) NSUInteger tapCount
在预先设定的时间内点按屏幕的次数,可根据此属性判断单击、双击。
 
@property(nonatomic, readonly) NSTimeInterval timestamp
touch 发生时或当它最后运动时的时间
 
@property(nonatomic, readonly) UITouchPhase phase
触摸事件在屏幕上有一个周期,即触摸开始、触摸点移动、触摸结束,还有中途取消。通过phase可以查看当前触摸事件在一个周期中所处的状态。phase是UITouchPhase类型的,是一个枚举配型,包含:
 
typedef NS_ENUM(NSInteger, UITouchPhase) {
    UITouchPhaseBegan,             // whenever a finger touches the surface.
    UITouchPhaseMoved,             // whenever a finger moves on the surface.
    UITouchPhaseStationary,        // whenever a finger is touching the surface but hasn‘t moved since the previous event.
    UITouchPhaseEnded,             // whenever a finger leaves the surface.
    UITouchPhaseCancelled,         // whenever a touch doesn‘t end but we need to stop tracking (e.g. putting device to face)
};
 
获取 touches 的位置
 
@property(nonatomic, readonly, copy) NSArray *gestureRecognizers
使用当前触摸对象的 UIGestureRecognizer 的数组

代码示例
 
单点触摸 - (让红色View 跟随手指位置移动)
 
@interface ViewController ()
@property (nonatomic, weak) UIView *redView;
@end
 
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 1. 实例化红色的视图
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(110, 100, 100, 100)];
    view.backgroundColor = [UIColor redColor];
    
    [self.view addSubview:view];
    
    self.redView = view;
}

#pragma mark - 移动
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touchesMoved");
    
    // 1. 获取到集合中的触摸对象
    UITouch *touch = [touches anyObject];
    // 2. 获取手指所在的位置
    CGPoint location = [touch locationInView:self.view];
    
    // 根据运行发现,手指第一次移动时,红色视图会出现跳跃的情况,会影响用户的使用
    // 1) 取出前一次的手指位置
    CGPoint preLocation = [touch previousLocationInView:self.view];
    
    // 2) 计算两次手指之间的距离差值
    CGPoint offset = CGPointMake(location.x - preLocation.x, location.y - preLocation.y);
    // 3) 修正红色视图的中心点
    CGPoint center = CGPointMake(_redView.center.x + offset.x, _redView.center.y + offset.y);
    
    // 3. 设置红色视图的位置
    self.redView.center = center;
}

 

多点触摸 - (两只手指画出不同的火花)
@interface MultiTouchViewController ()
@property (nonatomic, strong) NSArray *images;
@end
 
- (void)viewDidLoad
{
    [super viewDidLoad];

    // 初始化图像
    _images = @[[UIImage imageNamed:@"spark_blue"],
                [UIImage imageNamed:@"spark_red"]];
    
    // 让视图支持多选,如果不设置多点选项,默认只支持单点
    [self.view setMultipleTouchEnabled:YES];
}
#pragma mark - 触摸事件
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSInteger i = 0;
    
    for (UITouch *touch in touches) {
        // 2. 取出手指触摸位置
        CGPoint location = [touch locationInView:self.view];
        
        // 3. 在相应位置绘制图像
        UIImageView *imageView = [[UIImageView alloc] initWithImage:_images[i]];
        imageView.center = location;
        
        // 4. 添加到视图
        [self.view addSubview:imageView];
       
        // 5. 添加动画,让图像的透明度降低,然后消失
        [UIView animateWithDuration:1.0f animations:^{
            imageView.alpha = 0.5f;
        } completion:^(BOOL finished) {
            // 将图像视图从视图中删除
            [imageView removeFromSuperview];
        }];
        
        i++;
    }
}
 
 
运动事件 - (摇一摇)
 
/*
 1. 是否成为第一响应者是监听摇晃事件的关键!
 2. 在视图出现时,让视图控制器成为第一响应者
 3. 在视图消失时,让视图控制器注销第一响应者身份
 4. 监听摇晃运动事件
*/
 1 - (BOOL)canBecomeFirstResponder
 2 {
 3     return YES;
 4 }
 5 
 6 - (void)viewDidAppear:(BOOL)animated
 7 {
 8     [self becomeFirstResponder];
 9 }
10 
11 - (void)viewDidDisappear:(BOOL)animated
12 {
13     [self resignFirstResponder];
14 }
15 
16 #pragma mark 摇晃开始事件
17 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
18 {
19     if (motion == UIEventSubtypeMotionShake) {
20         NSLog(@"摇晃了");
21     }
22 }

iOS中的触摸事件

标签:

原文地址:http://www.cnblogs.com/kangshang/p/4418281.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!