码迷,mamicode.com
首页 > 其他好文 > 详细

事件处理

时间:2015-10-07 16:08:59      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

iOS中的事件

  • iOS中的事件可以分为3大类型:
    • 触摸事件
    • 加速计事件
    • 远程控制事件

     

  • 这里我们只讨论iOS中的触摸事件。

    技术分享

 

 

响应者对象(UIResponder)

学习触摸事件首先要了解一个比较重要的概念-响应者对象(UIResponder)。

  • 在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接受并处理事件,我们称之为“响应者对象”。以下都是继承自UIResponder的,所以都能接收并处理事件。
    • UIApplication
    • UIViewController
    • UIView

那么为什么继承自UIResponder的类就能够接收并处理事件呢?

  因为UIResponder中提供了以下4个对象方法来处理触摸事件。

UIResponder内部提供了以下方法来处理事件
触摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

加速计事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;

远程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

 

下面以UIView为例来说明触摸事件的处理

// UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件
// 一根或者多根手指开始触摸view,系统会自动调用view的下面方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

// 一根或者多根手指在view上移动,系统会自动调用view的下面方法(随着手指的移动,会持续调用该方法)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

// 一根或者多根手指离开view,系统会自动调用view的下面方法
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

// 触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用view的下面方法
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
// 提示:touches中存放的都是UITouch对象

需要注意的是:以上四个方法是由系统自动调用的,所以可以通过重写该方法来处理一些事件。

  • 如果两根手指同时触摸一个view,那么view只会调用一次touchesBegan:withEvent:方法,touches参数中装着2个UITouch对象
  • 如果这两根手指一前一后分开触摸同一个view,那么view会分别调用2次touchesBegan:withEvent:方法,并且每次调用时的touches参数中只包含一个UITouch对象
  • 重 写以上四个方法,如果是处理UIView的触摸事件。必须要自定义UIView子类继承自UIView。因为苹果不开源,没有把UIView的.m文件提 供给我们。我们只能通过子类继承父类,重写子类方法的方式处理UIView的触摸事件(注意:我说的是UIView触摸事件而不是说的 UIViewController的触摸事件)。如果是处理UIViewController的触摸事件,那么在控制器的.m文件中直接重写那四个方法即 可!

 

/************************自定义UIView的.h文件************************/
#import <UIKit/UIKit.h>

@interface WSView : UIView

@end

/************************自定义UIView的.m文件***********************/
#import "WSView.h"

@implementation WSView

// 开始触摸时就会调用一次这个方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"摸我干啥!");
}

// 手指移动就会调用这个方法
// 这个方法调用非常频繁
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"哎呀,不要拽人家!");
}

// 手指离开屏幕时就会调用一次这个方法
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"手放开还能继续玩耍!");
}


@end
/**************************k控制器的.m文件*************************/
#import "ViewController.h"
#import "WSView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 创建自定义view
    WSView *touchView = [[WSView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    // 背景颜色
    touchView.backgroundColor = [UIColor redColor];
    // 添加到父控件
    [self.view addSubview:touchView];
    
}
@end

 

注 意:有人认为,我要是处理控制器的自带的view的事件就不需要自定义UIView子类继承于UIView,因为可以在viewController.m 文件中重写touchBegan:withEvent:方法,但是,我们此处讨论的是处理UIView的触摸事件,而不是处理 UIViewController的触摸事件。你是在viewController.m文件中重写touchBegan:withEvent:方法,相当于处理的是viewController的触摸事件,因为viewController也是继承自UIResponder,所以会给人一种错觉。

所以,还是那句话,想处理UIView的触摸事件,必须自定义UIView子类继承自UIView。

UIView的拖拽

那么,如何实现UIView的拖拽呢?也就是让UIView随着手指的移动而移动。

  重写touchsMoved:withEvent:方法

此时需要用到参数touches,下面是UITouch的属性和方法:

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITouch : NSObject

@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

// 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(nonatomic,readonly,retain) UIWindow    *window;
@property(nonatomic,readonly,retain) UIView      *view;
@property(nonatomic,readonly,copy)   NSArray     *gestureRecognizers NS_AVAILABLE_IOS(3_2);

- (CGPoint)locationInView:(UIView *)view;
- (CGPoint)previousLocationInView:(UIView *)view;

@end

UITouch对象

  • 当用户用一根手指触摸屏幕时,会创建一个与手指相关的UITouch对象
  • 一根手指对应一个UITouch对象
  • 如果两根手指同时触摸一个view,那么view只会调用一次touchesBegan:withEvent:方法,touches参数中装着2个UITouch对象
  • 如果这两根手指一前一后分开触摸同一个view,那么view会分别调用2次touchesBegan:withEvent:方法,并且每次调用时的touches参数中只包含一个UITouch对象

UITouch的作用

  • 保存着跟手指相关的信息,比如触摸的位置、时间、阶段
  • 当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置
  • 当手指离开屏幕时,系统会销毁相应的UITouch对象
  • 提示:iPhone开发中,要避免使用双击事件!

UITouch的属性

  • 触摸产生时所处的窗口
    • @property(nonatomic,readonly,retain) UIWindow *window;
  • 触摸产生时所处的视图
    • @property(nonatomic,readonly,retain) UIView *view;
  • 短时间内点按屏幕的次数,可以根据tapCount判断单击、双击或更多的点击
    • @property(nonatomic,readonly) NSUInteger tapCount;
  • 记录了触摸事件产生或变化时的时间,单位是秒
    • @property(nonatomic,readonly) NSTimeInterval timestamp;
  • 当前触摸事件所处的状态
    • @property(nonatomic,readonly) UITouchPhase phase;

UITouch的方法

  • (CGPoint)locationInView:(UIView *)view;

    • 返回值表示触摸在view上的位置
    • 这里返回的位置是针对view的坐标系的(以view的左上角为原点(0, 0))
    • 调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置
  • (CGPoint)previousLocationInView:(UIView *)view;

    • 该方法记录了前一个触摸点的位置

 

事件处理

标签:

原文地址:http://www.cnblogs.com/wsnb/p/4858784.html

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