1、UIEvent简介

  UIEvent是代表iOS系统中的一个事件,一个事件包含一个或多个的UITouch

  UIEvent分为四类: UIEventType

typedef NS_ENUM(NSInteger, UIEventType) {
UIEventTypeTouches,//触摸事件类型 iOS3.0之后可以用
UIEventTypeMotion,//摇晃事件类型 iOS3.0之后可以用
UIEventTypeRemoteControl,//遥控事件类型 iOS4.0之后可以用
UIEventTypePresses NS_ENUM_AVAILABLE_IOS(9_0),//物理按钮事件类型 iOS9.0之后可以用
};

  子事件类型:UIEventSubtype

typedef NS_ENUM(NSInteger, UIEventSubtype) {
//事件没有子类型 iOS3.0之后可以用
UIEventSubtypeNone = , //事件子类型晃动的设备 iOS3.0之后可以用
UIEventSubtypeMotionShake = , //遥控的事件子类型 iOS4.0之后可以用
UIEventSubtypeRemoteControlPlay = ,//播放
UIEventSubtypeRemoteControlPause = ,//暂停
UIEventSubtypeRemoteControlStop = ,//停止
UIEventSubtypeRemoteControlTogglePlayPause = ,//播放和暂停之间切换【操作:播放或暂停状态下,按耳机线控中间按钮一下】
UIEventSubtypeRemoteControlNextTrack = ,//下一曲【操作:按耳机线控中间按钮两下】
UIEventSubtypeRemoteControlPreviousTrack = ,//上一曲【操作:按耳机线控中间按钮三下】
UIEventSubtypeRemoteControlBeginSeekingBackward = ,//快退开始【操作:按耳机线控中间按钮三下不要松开】
UIEventSubtypeRemoteControlEndSeekingBackward = ,//快退结束【操作:按耳机线控中间按钮三下到了快退的位置松开】
UIEventSubtypeRemoteControlBeginSeekingForward = ,//快进开始【操作:按耳机线控中间按钮两下不要松开】
UIEventSubtypeRemoteControlEndSeekingForward = ,//快进结束【操作:按耳机线控中间按钮两下到了快进的位置松开】
};

2、相关API

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;//事件发生时间 //返回与接收器相关联的所有触摸对象。
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly, nullable) NSSet <UITouch *> *allTouches;
#else
- (nullable NSSet <UITouch *> *)allTouches;
#endif
- (nullable NSSet <UITouch *> *)touchesForWindow:(UIWindow *)window;//返回属于一个给定视图的触摸对象,用于表示由接收器所表示的事件。
- (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

3、触摸事件示例

  相关方法:

- (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:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEstimatedPropertiesUpdated:(NSSet<UITouch *> *)touches NS_AVAILABLE_IOS(9_1);

  拖动和移动效果图:

  代码展示:

//拖动视图
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint currPoint = [touch locationInView:self.view];
CGPoint prePoint = [touch previousLocationInView:self.view];
CGRect frame = self.btnView.frame;
frame.origin.x += currPoint.x -prePoint.x;
frame.origin.y += currPoint.y -prePoint.y;
self.btnView.frame = frame;
} //点击移动
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGRect frame = self.btnView.frame;
frame.origin = [touch locationInView:self.view];
self.btnView.frame = frame;
}

4、摇晃事件示例

  相关方法:

- (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
- (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);

  效果图:模拟器摇一摇「Hardware」-「Shake Gesture」来测试 ,快捷键:command+control+z

  摇一摇显示随机图片:

@implementation MotionImageView
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.image = [self getImage];
}
return self;
} - (BOOL)canBecomeFirstResponder{
return YES;
} - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{
if (motion == UIEventSubtypeMotionShake) {
self.image = [self getImage];
}
}
- (UIImage *)getImage{
int index = arc4random() % +;
NSString *imageName = [NSString stringWithFormat:@"pic%i.png",index];
UIImage *image = [UIImage imageNamed:imageName];
return image; }
@end

  在ViewController中使用:

//成为第一响应者
- (void)viewDidAppear:(BOOL)animated{
[self.imageView becomeFirstResponder];
}
//注销第一响应者
- (void)viewDidDisappear:(BOOL)animated{
[self.imageView resignFirstResponder];
}
//支持摇一摇功能
- (void)viewDidLoad {
[super viewDidLoad];
[UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;
}

5、遥控事件示例

  相关方法:

- (void)remoteControlReceivedWithEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(4_0);

  代码实现:

#import "VideoViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface VideoViewController ()
{
UIButton *_playButton;
BOOL _isPlaying;
AVPlayer *_player;
}
@end @implementation VideoViewController - (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://music.163.com/song/media/outer/url?id=1293886117.mp3"];
_player = [[AVPlayer alloc] initWithURL:url];
} #pragma mark 远程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event{
if(event.type == UIEventTypeRemoteControl){
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:
[_player play];
_isPlaying = true;
NSLog(@"播放");
break;
case UIEventSubtypeRemoteControlTogglePlayPause:
[self btnClick:_playButton];
NSLog(@"播放和暂停之间切换【操作:播放或暂停状态下,按耳机线控中间按钮一下】");
break;
case UIEventSubtypeRemoteControlNextTrack:
NSLog(@"下一曲【操作:按耳机线控中间按钮两下】");
break;
case UIEventSubtypeRemoteControlPreviousTrack:
NSLog(@"上一曲【操作:按耳机线控中间按钮三下】");
break;
case UIEventSubtypeRemoteControlBeginSeekingForward:
NSLog(@"快进开始【操作:按耳机线控中间按钮两下不要松开】");
break;
case UIEventSubtypeRemoteControlEndSeekingForward:
NSLog(@"快进结束【操作:按耳机线控中间按钮两下到了快进的位置松开】");
break;
case UIEventSubtypeRemoteControlBeginSeekingBackward:
NSLog(@"快退开始【操作:按耳机线控中间按钮三下不要松开】");
break;
case UIEventSubtypeRemoteControlEndSeekingBackward:
NSLog(@"快退结束【操作:按耳机线控中间按钮三下到了快退的位置松开】");
break;
case UIEventSubtypeRemoteControlStop:
NSLog(@"停止");
break;
case UIEventSubtypeRemoteControlPause:
NSLog(@"暂停");
break;
default:
break;
}
[self changeUIState];
} } #pragma mark 界面布局
- (void)initLayout{
//专辑封面
UIImageView *imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
imageView.image = [UIImage imageNamed:@"pic1.jpg"];
imageView.contentMode = UIViewContentModeScaleAspectFill;
[self.view addSubview:imageView]; //播放控制面板
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(, , [UIScreen mainScreen].bounds.size.width, )];
view.backgroundColor = [UIColor yellowColor];
view.alpha = 0.9;
[self.view addSubview:view]; //添加播放按钮
_playButton = [UIButton buttonWithType:UIButtonTypeCustom];
_playButton.bounds = CGRectMake(, , , );
_playButton.center = CGPointMake(CGRectGetWidth(view.frame)/,CGRectGetHeight(view.frame)/);
[self changeUIState];
[_playButton addTarget:self
action:@selector(btnClick:)
forControlEvents:UIControlEventTouchUpInside];
[view addSubview:_playButton]; } #pragma mark 界面状态
- (void)changeUIState{
if(_isPlaying){
UIImage *pauseImage = [UIImage imageNamed:@"pic2.png"];
[_playButton setImage:pauseImage forState:UIControlStateNormal];
}else{
UIImage *playImage = [UIImage imageNamed:@"pic3.png"];
[_playButton setImage:playImage forState:UIControlStateNormal];
}
} - (void)btnClick:(UIButton *)btn{
if (_isPlaying) {
[_player pause];
}else{
[_player play];
}
_isPlaying =! _isPlaying;
[self changeUIState];
}
@end

线控代码实现

  号外1:获取网易云mp3路径

  号外2:后台播放音乐

- (void)applicationWillResignActive:(UIApplication *)application {
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
}

6、物理按钮示例

  按压事件代表了对一个游戏控制器,苹果TV远程,或其他有物理按钮的设备之间的交互。;

  所以对于iPhone的手机而言在没有物理按键连接的情况下,是无法触发该事件的;

  相关方法:

//物理按钮 深按API,一般用于遥控器
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);// 开始按压的时候调用
- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);// 按压改变的时候调用
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);// 按压结束的时候调用
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);// 当系统发出取消按压事件的时候调用

  UIPress相关API

NS_ENUM_AVAILABLE_IOS(9_0) typedef NS_ENUM(NSInteger, UIPressPhase) {
UIPressPhaseBegan, // 开始
UIPressPhaseChanged, // 变化
UIPressPhaseStationary, // 按下不动时
UIPressPhaseEnded, // 结束
UIPressPhaseCancelled, // 取消
}; NS_ENUM_AVAILABLE_IOS(9_0) typedef NS_ENUM(NSInteger, UIPressType) {
UIPressTypeUpArrow, //向上的键被按压
UIPressTypeDownArrow, //向下的键被按压
UIPressTypeLeftArrow, //向左的键被按压
UIPressTypeRightArrow, //向右的键被按压 UIPressTypeSelect, //选择 的键被按压
UIPressTypeMenu, //菜单 的键被按压
UIPressTypePlayPause, //播放/暂停 的键被按压
}; NS_CLASS_AVAILABLE_IOS(9_0) @interface UIPress : NSObject @property(nonatomic,readonly) NSTimeInterval timestamp; //时间
@property(nonatomic,readonly) UIPressPhase phase; //按下阶段
@property(nonatomic,readonly) UIPressType type; //按下的类型 @property(nullable,nonatomic,readonly,strong) UIWindow *window; //所处视图
@property(nullable,nonatomic,readonly,strong) UIResponder *responder;//
@property(nullable,nonatomic,readonly,copy) NSArray <UIGestureRecognizer *> *gestureRecognizers;//手势 @property(nonatomic, readonly) CGFloat force; //按钮按压的力 返回一个介于0和1之间的值。数字按钮返回0或1。

最新文章

  1. php继承多态
  2. jmeter jar包
  3. git pull 和本地文件冲突问题解决
  4. pip安装教程
  5. Ubuntu 16.10 虚拟机安装记录
  6. LeetCode 笔记24 Palindrome Partitioning II (智商碾压)
  7. Div+Css的初步运用
  8. Android -------- 网络访问数据
  9. 团队作业4----第一次项目冲刺(Alpha版本)4.28
  10. 【CJOJ2316】【模板】可持久化线段树
  11. javascript进阶高手必备知识
  12. 隐藏马尔科夫模型HMM
  13. nginx通过反向代理实现未备案域名访问详解
  14. SignalR2结合ujtopo实现拓扑图动态变化
  15. 一个div中有一个a标签,点击a标签的时候不进入div的点击事件
  16. 【神经网络】LSTM 网络
  17. Asp.Net MVC WebApi2 自动生成帮助文档
  18. dede中arcurl的解析
  19. TextBox 加阴影
  20. hdu1 247 Hat’s Words(字典树)

热门文章

  1. sql 关系模型
  2. 栈+括号序列+暴力枚举——cf1248D1
  3. vue简单的input校验手机号
  4. [Luogu P4178]Tree 题解(点分治+平衡树)
  5. element not visible的解决方法
  6. 前台处理ajax:axios
  7. 假如Kafka集群中一个broker宕机无法恢复,应该如何处理?
  8. 2019牛客多校第三场B-Crazy Binary String(前缀和+思维)
  9. 2019 牛客多校第六场 D Move
  10. js小项目:显示与输入的内容相关的