你真的了解UIEvent、UITouch吗?

一:首先查看一下关于UIEvent的定义

//事件类型
typedef NS_ENUM(NSInteger, UIEventType) {
    UIEventTypeTouches,
    UIEventTypeMotion,
    UIEventTypeRemoteControl,
};

 // 触摸事件的类型
typedef NS_ENUM(NSInteger, UIEventSubtype) {

    UIEventSubtypeNone                              = 0,
    //摇晃 
    UIEventSubtypeMotionShake                       = 1,
   //播放
    UIEventSubtypeRemoteControlPlay                 = 100,
   //暂停
    UIEventSubtypeRemoteControlPause                = 101,
    //停止
    UIEventSubtypeRemoteControlStop                 = 102,
    //播放和暂停切换 
    UIEventSubtypeRemoteControlTogglePlayPause      = 103,
    //下一首
    UIEventSubtypeRemoteControlNextTrack            = 104,
    //上一首
    UIEventSubtypeRemoteControlPreviousTrack        = 105,
     //开始后退 
    UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
    //结束后退 
    UIEventSubtypeRemoteControlEndSeekingBackward   = 107,
    //开始快进 
    UIEventSubtypeRemoteControlBeginSeekingForward  = 108,
    //结束快进
    UIEventSubtypeRemoteControlEndSeekingForward    = 109,
};

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIEvent : NSObject
//事件类型
@property(nonatomic,readonly) UIEventType     type NS_AVAILABLE_IOS(3_0);
// 触摸事件的类型
@property(nonatomic,readonly) UIEventSubtype  subtype NS_AVAILABLE_IOS(3_0);

//事件的时间戳
@property(nonatomic,readonly) NSTimeInterval  timestamp;

//所有的触摸 
- (nullable NSSet <UITouch *> *)allTouches;
//获得UIWindow的触摸
- (nullable NSSet <UITouch *> *)touchesForWindow:(UIWindow *)window;
//获得UIView的触摸  
- (nullable NSSet <UITouch *> *)touchesForView:(UIView *)view;
//获得事件中特定手势的触摸
- (nullable NSSet <UITouch *> *)touchesForGestureRecognizer:(UIGestureRecognizer *)gesture NS_AVAILABLE_IOS(3_2);

//会将丢失的触摸放到一个新的 UIEvent 数组中,你可以用 coalescedTouchesForTouch(_:) 方法来访问
- (nullable NSArray <UITouch *> *)coalescedTouchesForTouch:(UITouch *)touch NS_AVAILABLE_IOS(9_0);
//辅助UITouch的触摸,预测发生了一系列主要的触摸事件。这些预测可能不完全匹配的触摸的真正的行为,因为它的移动,所以他们应该被解释为一个估计。
- (nullable NSArray <UITouch *> *)predictedTouchesForTouch:(UITouch *)touch NS_AVAILABLE_IOS(9_0);

@end

UIEvent是代表iOS系统中的一个事件,一个事件包含一个或多个的UITouch;UIEvent分为三类:UIEventTypeTouches触摸事件(通过触摸、手势进行触发,例如手指点击、缩放)、UIEventTypeMotion运动事件,通过加速器进行触发(例如手机晃动)、UIEventTypeRemoteControl远程控制事件通过其他远程设备触发(例如耳机控制按钮);

知识点1:在iOS中并不是所有的类都能处理接收并事件,只有继承自UIResponder类的对象才能处理事件,(如我们常用的UIView、UIViewController、UIApplication都继承自UIResponder,它们都能接收并处理事件)。在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 NS_AVAILABLE_IOS(3_0);
运动开始时执行;

(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0);
运动结束后执行;

(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0);
运动被意外取消时执行;

远程控制事件:

(void)remoteControlReceivedWithEvent:(UIEvent *)event NS_AVAILABLE_IOS(4_0);
接收到远程控制消息时执行;

知识点2:iOS「摇一摇」功能的实现(运动事件的运用)

- (void)viewDidLoad {
[super viewDidLoad];
// 设置允许摇一摇功能
[UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;
// 并让自己成为第一响应者
[self becomeFirstResponder];
return;
}

//摇一摇相关方法
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"开始摇动");
return;
}  

- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"取消摇动");
return;
}  

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (event.subtype == UIEventSubtypeMotionShake) { // 判断是否是摇动结束
    NSLog(@"摇动结束");
}
return;
}

另外:监听运动事件前提,监听对象必须成为第一响应者;在模拟器中运行时,可以通过「Hardware」-「Shake Gesture」来测试「摇一摇」功能

知识点3:一个摇动随机图片显示的实例(运动事件的运用)

KCImageView.m

#import "KCImageView.h"

#define kImageCount 3

@implementation KCImageView

- (instancetype)initWithFrame:(CGRect)frame {

self = [super initWithFrame:frame];

if (self) {

self.image = [self getImage];

}

return self;

}

#pragma mark 设置控件可以成为第一响应者

- (BOOL)canBecomeFirstResponder{

return YES;

}

#pragma mark 运动开始

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{

//这里只处理摇晃事件

if (motion == UIEventSubtypeMotionShake) {

self.image = [self getImage];

}

}

#pragma mark 运动结束

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{

}

#pragma mark 随机取得图片

- (UIImage *)getImage{

int index = arc4random() % kImageCount;

NSString *imageName = [NSString stringWithFormat:@"avatar%i.png",index];

UIImage *image = [UIImage imageNamed:imageName];

return image;

}

@end

KCShakeViewController.m

#import "KCShakeViewController.h"

#import "KCImageView.h"

@interface KCShakeViewController (){

KCImageView *_imageView;

}

@end

@implementation KCShakeViewController

- (void)viewDidLoad {

[super viewDidLoad];

}

#pragma mark 视图显示时让控件变成第一响应者

- (void)viewDidAppear:(BOOL)animated{

_imageView = [[KCImageView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];

_imageView.userInteractionEnabled = true;

[self.view addSubview:_imageView];

[_imageView becomeFirstResponder];

}

#pragma mark 视图不显示时注销控件第一响应者的身份

- (void)viewDidDisappear:(BOOL)animated{

[_imageView resignFirstResponder];

}

@end

知识点4:远程控制事件的运用

iOS远程控制事件,是通过其他远程设备触发的(比如耳机控制按钮),iOS远程控制事件相关的只有-(void)remoteControlReceivedWithEvent:(UIEvent *)event;监听远程控制事件的前提:启动远程事件接收,调用[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];UI控件同样要求必须成为第一响应者【使用参考运动事件】,但如果是视图控制器或UIApplication,就没有要求成为第一响应者,应用程序必须是 当前音频额控制者,目前iOS7给我们的远程控制权限仅限于音频控制;

一个关于音乐远程控制实例:

#import "ViewController.h"

@interface ViewController (){

UIButton *_playButton;

BOOL _isPlaying;

}

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

[self initLayout];

}

- (BOOL)canBecomeFirstResponder{

return NO;

}

- (void)viewDidAppear:(BOOL)animated{

[super viewDidAppear:animated];

NSURL *url = [NSURL URLWithString:@"http://stream.jewishmusicstream.com:8000"];

_player = [[AVPlayer alloc] initWithURL:url];

}

#pragma mark 远程控制事件

- (void)remoteControlReceivedWithEvent:(UIEvent *)event{

if(event.type == UIEventTypeRemoteControl){

switch (event.subtype) {

case UIEventSubtypeRemoteControlPlay:

[_player play];

_isPlaying = true;

break;

case UIEventSubtypeRemoteControlTogglePlayPause:

[self btnClick:_playButton];

break;

case UIEventSubtypeRemoteControlNextTrack:

NSLog(@"Next...");

break;

case UIEventSubtypeRemoteControlPreviousTrack:

NSLog(@"Previous...");

break;

case UIEventSubtypeRemoteControlBeginSeekingForward:

NSLog(@"Begin seek forward...");

break;

case UIEventSubtypeRemoteControlEndSeekingForward:

NSLog(@"End seek forward...");

break;

case UIEventSubtypeRemoteControlBeginSeekingBackward:

NSLog(@"Begin seek backward...");

break;

case UIEventSubtypeRemoteControlEndSeekingBackward:

NSLog(@"End seek backward...");

break;

default:

break;

}

[self changeUIState];

}

}

#pragma mark 界面布局

- (void)initLayout{

//专辑封面

UIImage *image = [UIImage imageNamed:@"wxl.jpg"];

CGRect *frame = [UIScreen mainScreen].applicationFrame;

UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];

imageView.image = image;

imageView.contentMode = UIViewContentModeScaleAspectFill;

[self.view addSubview:imageView];

//播放控制面板

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 480, 320, 88)];

view.backgroundColor = [UIColor lightGrayColor];

view.alpha = 0.9;

[self.view addSubview:view];

//添加播放按钮

_playButton = [UIButton buttonWithType:UIButtonTypeCustom];

_playButton.bounds = CGRectMake(0, 0, 50, 50);

CGFloat playBtnX = view.frame.size.width/2;

CGFloat playBtnY = view.frame.size.height/2;

_playButton.center = CGPointMake(playBtnX, playBtnY);

[self changeUIState];

[_playButton addTarget:self

action:@selector(btnClick:)

forControlEvents:UIControlEventTouchUpInside];

[view addSubview:_playButton];

}

#pragma mark 界面状态

- (void)changeUIState{

if(_isPlaying){

UIImage *pauseImage = [UIImage imageNamed:@"playing_btn_pause_n.png"];

UIImage *pauseImageH = [UIImage imageNamed:@"playing_btn_pause_h.png"];

[_playButton setImage:pauseImage forState:UIControlStateNormal];

[_playButton setImage:pauseImageH forState:UIControlStateHighlighted];

}else{

UIImage *playImage = [UIImage imageNamed:@"playing_btn_play_n.png"];

UIImage *playImageH = [UIImage imageNamed:@"playing_btn_play_h.png"];

[_playButton setImage:playImage forState:UIControlStateNormal];

[_playButton setImage:playImageH forState:UIControlStateHighlighted];

}

}

- (void)btnClick:(UIButton *)btn{

if (_isPlaying) {

[_player pause];

}else{

[_player play];

}

_isPlaying =! _isPlaying;

[self changeUIState];

}

@end

二:首先查看一下关于UITouch的定义

//触摸事件在屏幕上有一个周期
typedef NS_ENUM(NSInteger, UITouchPhase) {
    UITouchPhaseBegan,           //开始触摸
    UITouchPhaseMoved,           //移动
    UITouchPhaseStationary,      //停留
    UITouchPhaseEnded,            //触摸结束
    UITouchPhaseCancelled,       //触摸中断
};

//检测是否支持3DTouch
typedef NS_ENUM(NSInteger, UIForceTouchCapability) {
    UIForceTouchCapabilityUnknown = 0,  //3D Touch检测失败
    UIForceTouchCapabilityUnavailable = 1,  //3D Touch不可用
    UIForceTouchCapabilityAvailable = 2  //3D Touch可用
};

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITouch : NSObject

//触摸产生或变化的时间戳 只读
@property(nonatomic,readonly) NSTimeInterval      timestamp;
//触摸周期内的各个状态
@property(nonatomic,readonly) UITouchPhase        phase;
//短时间内点击的次数 只读
@property(nonatomic,readonly) NSUInteger          tapCount;   

//获取手指与屏幕的接触半径 IOS8以后可用 只读
@property(nonatomic,readonly) CGFloat majorRadius NS_AVAILABLE_IOS(8_0);
//获取手指与屏幕的接触半径的误差 IOS8以后可用 只读
@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);

//取得在指定视图的位置
// 返回值表示触摸在view上的位置
// 这里返回的位置是针对view的坐标系的(以view的左上角为原点(0,0))
// 调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置
- (CGPoint)locationInView:(nullable UIView *)view;
//该方法记录了前一个触摸点的位置
- (CGPoint)previousLocationInView:(nullable UIView *)view;

//获取触摸压力值,一般的压力感应值为1.0 IOS9 只读
@property(nonatomic,readonly) CGFloat force NS_AVAILABLE_IOS(9_0);

//获取最大触摸压力值
@property(nonatomic,readonly) CGFloat maximumPossibleForce NS_AVAILABLE_IOS(9_0);

@end

知识点1:触摸时,图片移动(实例)

- (void)viewDidLoad
{
    UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(20.0, 50.0, 45.0, 45.0)];
    image.image = [UIImage imageNamed:@"baby.png"];
    image.tag = 100;
    [self.view addSubview:image];  

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}  

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    UIImageView *view1 = (UIImageView*)[self.view  viewWithTag:100];
    CGPoint point = [touch  locationInView:self.view];
    CGRect  frame = view1.frame;
    frame.origin = point;
    view1.frame = frame;
}

知识点2:创建可以拖动的视图

CGPoint originalLocation;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    originalLocation = [touch locationInView:self.view];
}  

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint currentLocation = [touch locationInView:self.view];
    CGRect frame = self.view.frame;
    frame.origin.x += currentLocation.x-originalLocation.x;
    frame.origin.y += currentLocation.y-originalLocation.y;
    self.view.frame = frame;
} 

这里先在touchesBegan中通过[touch locationInView:self.view]获取手指触摸在当前视图上的位置,用CGPoint变量记录,然后在手指移动事件touchesMoved方法中获取触摸对象当前位置,并通过于与原始位置的差值计算出移动偏移量,再设置当前视图的位置。

时间: 2024-08-08 08:58:29

你真的了解UIEvent、UITouch吗?的相关文章

iOS:触摸控件UITouch、事件类UIEvent

UITouch:触摸控件类   UIEvent:事件类 ??????UITouch的介绍?????? 一.触摸状态类型枚举 typedef NS_ENUM(NSInteger, UITouchPhase) { UITouchPhaseBegan,             // 开始触摸 UITouchPhaseMoved,             // 触摸移动 UITouchPhaseStationary,       // 触摸没有移动 UITouchPhaseEnded,        

IOS开发——UI进阶篇(十二)事件处理,触摸事件,UITouch,UIEvent,响应者链条,手势识别

触摸事件 在用户使用app过程中,会产生各种各样的事件 一.iOS中的事件可以分为3大类型 触摸事件加速计事件远程控制事件 响应者对象在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件.我们称之为“响应者对象” UIApplication.UIViewController.UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件 二.UIResponder UIResponder内部提供了以下方法来处理事件触摸事件- (v

IOS开发—事件处理,触摸事件,UITouch,UIEvent,响应者链条,手势识别

触摸事件 在用户使用app过程中,会产生各种各样的事件 一.iOS中的事件可以分为3大类型 触摸事件加速计事件远程控制事件 响应者对象在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件.我们称之为“响应者对象” UIApplication.UIViewController.UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件 二.UIResponder UIResponder内部提供了以下方法来处理事件触摸事件- (v

UITouch触摸事件

UITouch触摸事件 主要为三个方法 1.-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{2.3. UITouch *touch = [touches anyObject];4. CGPoint point = [touch locationInView:self];5. start = point;6. end = point;7.8.}9.10.-(void)touchesMoved:(NSSet *)touc

UITouch手指滑动屏幕,屏幕跟着移动

1.//当手指在屏幕上滑动时 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch  = [touches anyObject]; CGPoint previousPoint = [touch previousLocationInView:self]; CGPoint currentPoint = [touch locationInView:self]; CGPoint newCenter

你真的了解UIScrollView吗?

一:首先查看一下关于UIScrollView的定义 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIScrollView : UIView <NSCoding> //表示UIScrollView滚动的位置(就是内容左上角与scrollView左上角的间距!!) @property(nonatomic) CGPoint contentOffset; // default CGPointZero //表示UIScrollView内容的尺寸,滚动范围 @proper

UIEvent

// UIEvent:是由设备捕捉到用户对硬件的操作,每个时间都是一个UIevent对象//iOS中的时间有三种:触摸事件,摇晃时间,以及远程控制事件//触摸事件:是由用户对屏幕通过接触产生的事件//对于UIView或者UIView的子类,都能接收到触摸事件,只是没有对于接触事件做出响应//iOS支持多点触摸  如果一个视图想要对触摸事件做出响应,只需在该类中实现touchBegan:touchEnded:touchMoved:  等触摸方法.//修改自身视图颜色 - (void)changeS

利用uitouch简单的实现了微信cell效果

#import <UIKit/UIKit.h> @interface weixinControl : UIControl -(weixinControl *)initWithFram:(CGRect)rect; @end #import "weixinControl.h" @implementation weixinControl { CGRect _rect; //记录self.frame的大小 UIView *_frontView; //用来显示主要内容 CGPoint

进击的UI---------------------UIEvent&amp;UITouch&amp;UIResponder

1.UIEvent(事件) 1??:事件分为三种:1 触摸事件 2 晃动事件 3 远程控制 2??:触摸事件 //1. UIControlEventTouchUpInside     点击进去(点后松手) //2. UIControlEventTouchDown         单击(点就出) //3. UIControlEventTouchDownRepeat   双击 //4. UIControlEventTouchDragInside   点一点,拽一拽(Button内) //5. UIC