iOS学习笔记07-运动事件和远程控制
之前我们已经学习了触摸处理和手势识别,其实这两个同属于iOS事件的触摸事件,今天我们来学习下iOS事件的另外两个事件:
一、运动事件
运动事件,是通过加速器进行触发,和触摸事件一样,继承UIResponder类的对象才能处理运动事件
UIResponder处理运动事件的方法:
#pragma mark 运动开始时执行
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
#pragma mark 运动结束后执行
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
#pragma mark 运动被意外取消时执行
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;
你没有看错,这里说的运动事件,只是摇晃一下手机而已,所以只有运动开始、运动结束、运动取消,无法取得运动过程中的运动速度、运动方向等数据,这些需要另外的框架去实现,我们可以理解这里的运动时间为 “摆动事件” 。
监听运动事件前提:
- 监听对象必须成为第一响应者,控件需要
- (BOOL)canBecomeFirstResponder方法返回YES - 在视图控制器的
- (void)viewWillAppear:(BOOL)animated方法中调用运动控件的becomeFirstResponder方法,使控件显示时成为第一响应者 - 在视图控制器的
- (void)viewDidDisappear:(BOOL)animated方法中调用运动控件的resignFirstResponder方法,使控件不显示时注销控件的第一响应者身份
实例:
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

二、远程控制事件
iOS远程控制事件,是通过其他远程设备触发的(比如耳机控制按钮),iOS远程控制事件相关的只有-(void)remoteControlReceivedWithEvent:(UIEvent *)event
监听远程控制事件的前提:
- 启动远程事件接收,调用
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; - UI控件同样要求必须成为第一响应者【使用参考运动事件】
但如果是视图控制器或UIApplication,就没有要求成为第一响应者 - 应用程序必须是 当前音频额控制者
目前iOS7给我们的远程控制权限仅限于音频控制
typedef NS_ENUM(NSInteger, UIEventSubtype) {
// 不包含任何子事件类型
UIEventSubtypeNone = 0,
// 摇晃事件(从iOS3.0开始支持此事件)
UIEventSubtypeMotionShake = 1,
//远程控制子事件类型(从iOS4.0开始支持远程控制事件)
//播放事件【操作:停止状态下,按耳机线控中间按钮一下】
UIEventSubtypeRemoteControlPlay = 100,
//暂停事件
UIEventSubtypeRemoteControlPause = 101,
//停止事件
UIEventSubtypeRemoteControlStop = 102,
//播放或暂停切换【操作:播放或暂停状态下,按耳机线控中间按钮一下】
UIEventSubtypeRemoteControlTogglePlayPause = 103,
//下一曲【操作:按耳机线控中间按钮两下】
UIEventSubtypeRemoteControlNextTrack = 104,
//上一曲【操作:按耳机线控中间按钮三下】
UIEventSubtypeRemoteControlPreviousTrack = 105,
//快退开始【操作:按耳机线控中间按钮三下不要松开】
UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
//快退停止【操作:按耳机线控中间按钮三下到了快退的位置松开】
UIEventSubtypeRemoteControlEndSeekingBackward = 107,
//快进开始【操作:按耳机线控中间按钮两下不要松开】
UIEventSubtypeRemoteControlBeginSeekingForward = 108,
//快进停止【操作:按耳机线控中间按钮两下到了快进的位置松开】
UIEventSubtypeRemoteControlEndSeekingForward = 109,
};
实例:
#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

这次笔记贴了很多代码,是因为这两个事件使用简单,理论知识不多,光讲理论,也不好理解,贴代码非常直观。
iOS学习笔记07-运动事件和远程控制的更多相关文章
- iOS学习笔记之触摸事件&UIResponder
iOS学习笔记之触摸事件&UIResponder 触摸事件 与触摸事件相关的四个方法如下: 一根手指或多根手指触摸屏幕 -(void)touchesBegan:(NSSet *)touches ...
- iOS学习笔记05-触摸事件
一.事件分发处理[由外到内] 在iOS中发生触摸后,事件会加到UIApplication事件队列,UIApplication会从事件队列取出最前面的事件进行分发处理,通常会先分发给主窗口,主窗口会调用 ...
- iOS学习笔记-精华整理
iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...
- iOS学习笔记总结整理
来源:http://mobile.51cto.com/iphone-386851_all.htm 学习IOS开发这对于一个初学者来说,是一件非常挠头的事情.其实学习IOS开发无外乎平时的积累与总结.下 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- iOS学习笔记之UITableViewController&UITableView
iOS学习笔记之UITableViewController&UITableView 写在前面 上个月末到现在一直都在忙实验室的事情,与导师讨论之后,发现目前在实验室完成的工作还不足以写成毕业论 ...
- IOS学习笔记48--一些常见的IOS知识点+面试题
IOS学习笔记48--一些常见的IOS知识点+面试题 1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...
- iOS学习笔记-自己动手写RESideMenu
代码地址如下:http://www.demodashi.com/demo/11683.html 很多app都实现了类似RESideMenu的效果,RESideMenu是Github上面一个stars数 ...
- iOS学习笔记-自定义过渡动画
代码地址如下:http://www.demodashi.com/demo/11678.html 这篇笔记翻译自raywenderlick网站的过渡动画的一篇文章,原文用的swift,由于考虑到swif ...
随机推荐
- 浅析document和window的区别
1.执行时间 window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行. $(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕. 2 ...
- 【数据分析 R语言实战】学习笔记 第十一章 对应分析
11.2对应分析 在很多情况下,我们所关心的不仅仅是行或列变量本身,而是行变量和列变量的相互关系,这就是因子分析等方法无法解释的了.1970年法国统计学家J.P.Benzenci提出对应分析,也称关联 ...
- 基于phpExcel写的excel类(导出为Excel)
<?php /* * 类的功能 * 传入二位数组导出excel * 传入excel 导出二位数组 * @author mrwu */ require('PHPExcel.php'); requi ...
- jdbc接口的一种类比——打酱油
jdbc很简单,这里只是为了方便自己的记忆.模型也许有缺陷,但本质是相同的. jdbc可以屏蔽数据库的底层的不同,让我们有能力用java语言统一访问不同的数据库.就像打酱油一样,可以去超市买,也可以去 ...
- Injection of autowired dependencies failed;错误解决
代码自动生成的时候可能出现这个问题,反正我是找了半天才发现.serviceimp层不要写抽象类的声明abstract,这个删掉.
- input提示文字;placeholder字体修改
在很多网站上我们都看到input输入框显示提示文字,让我们一起来看看如果在input输入框中显示提示文字.我们只需要在<input>标签里添加:placeholder="提示文字 ...
- 连接器前置挂载U盾
连接器前置挂载U盾 1. 宿主机配置及其信息 虚拟化软件版本 主机名 宿主机IP 账号及其密码 WorkStation windows idca- vm01 172.16.6.30 * Qemu-kv ...
- 基于PassThru的NDIS中间层驱动程序扩展
基于PassThru的NDIS中间层驱动程序扩展 独孤求真 概要:开发一个NDIS驱动是一项相对复杂的工作,这一方面是由于核心驱动本身 ...
- ios之NSNumber
NSNumber + (NSNumber *)numberWithInt:(int)value; + (NSNumber *)numberWithDouble:(double)value; - (in ...
- Java--泛型理解和使用 (List<String> list = new ArrayList<String>(); )
List<String> list = new ArrayList<String>(); 第一次看到这行代码是一头雾水,查了好久才弄清楚这是什么东西,怎么用,所以记录下来,方便 ...