iOS开发之运动事件和远程控制

之前我们已经学习了触摸处理和手势识别,其实这两个同属于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

远程控制实例效果

这次笔记贴了很多代码,是因为这两个事件使用简单,理论知识不多,光讲理论,也不好理解,贴代码非常直观。

(0)

相关推荐

  • IOS如何在Host App 与 App Extension 之间发送通知

    如何从你的一个App发送通知给另一个App? (例:搜狗输入法下载皮肤完成后使用皮肤) 注:搜狗输入法是App.而键盘是Extension 当你为你的App 添加 App Extension时,如果想在App 发送通知给 Extension或许这篇文章可以帮助你. 了解更多内容 // 发送通知 - (void)postNotificaiton { CFNotificationCenterRef notification = CFNotificationCenterGetDarwinNotifyC

  • iOS10最新实现远程通知的开发教程详解

    一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出现的Category(分类, 也可称之为快捷回复), iOS9出现的Text Input action(文本框快捷回复). 而在iOS10, 苹果可谓是大刀阔斧般的, 对远程通知和本地通知进行了大范围的更新. iOS10推出了全新的UserNotifications框架(iOS10之前从属于UIKi

  • iOS实现远程推送原理及过程

    推送通知,是现在的应用必不可少的功能.那么在 iOS 中,我们是如何实现远程推送的呢?iOS 的远程推送原理又是什么呢?在做 iOS 远程推送时,我们会遇到各种各样的问题.那么首先让我们准备一些做推送需要的东西.我们需要一个付费的苹果开发者账号(免费的不可以做远程推送),有了开发者账号,我们可以去苹果开发者网站,配置自己所需要的推送的相关证书.然后下载证书,供我们后面使用,详细的证书配置过程,我们下面再说. 首先我们要说说iOS推送通知的基本原理: 苹果的推送服务通知是由自己专门的推送服务器AP

  • iOS中的通知机制

    网上经常说iOS的通知机制是使用了观察者模式,里面有两个角色,其一是poster(发送者),另一个是observer(接受信息的订阅者).但我认为重要的角色是通知中心,它是整个通知机制的核心,有poster发送者发送的消息必定要到达通知中心,再由通知中心根据这个消息被哪些observer订阅者订阅过,就把消息往那些订阅者去分发.整体可以与现在的电子邮件结构作类比的. 但要额外说明一下,iOS的通知虽然也叫Notification通知,但是与Android中的通知是不一样的,在Android中的通

  • iOS10 适配远程推送功能实现代码

    iOS10正式版发布之后,网上各种适配XCode8以及iOS10的文章满天飞.但对于iOS10适配远程推送的文章却不多.iOS10对于推送的修改还是非常大的,新增了UserNotifications Framework,今天就结合自己的项目,说一说实际适配的情况. 一.Capabilities中打开Push Notifications 开关 在XCode7中这里的开关不打卡,推送也是可以正常使用的,但是在XCode8中,这里的开关必须要打开,不然会报错: Error Domain=NSCocoa

  • iOS推送之本地通知UILocalNotification

    摘要: Notification是智能手机应用编程中非常常用的一种传递信息的机制,而且可以非常好的节省资源,不用消耗资源来不停地检查信息状态(Pooling),在iOS下应用分为两种不同的Notification种类,本地和远程.本地的Notification由iOS下NotificationManager统一管理,只需要将封装好的本地Notification对象加入到系统Notification管理机制队列中,系统会在指定的时间激发将本地Notification,应用只需设计好处理Notifi

  • iOS远程推送Push开发教程

    远程推送通知 什么是远程推送通知 顾名思义,就是从远程服务器推送给客户端的通知(需要联网)远程推送服务,又称为APNs(Apple Push Notification Services) 为什么需要远程推送通知 传统获取数据的局限性 只要用户关闭了app,就无法跟app的服务器沟通,无法从服务器上获得最新的数据内容 远程推送通知可以解决以上问题 不管用户打开还是关闭app,只要联网了,都能接收到服务器推送的远程通知 远程推送通知使用须知 所有的苹果设备,在联网状态下,都会与苹果的服务器建立长连接

  • iOS消息远程推送通知

    本文实例为大家分享了iOS消息推送.iOS远程通知代码,供大家参考,具体内容如下 消息推送 /* 要开发测试消息机制的程序,必须用真机测试 推送消息的类型 UIRemoteNotificationTypeNone 不接收推送消息 UIRemoteNotificationTypeBadge 接收图标数字 UIRemoteNotificationTypeSound 接收音频 UIRemoteNotificationTypeAlert 接收消息文字 UIRemoteNotificationTypeNe

  • iOS10推送通知开发教程

    虽然通知经常被过度使用,但是通知确实是一种获得用户关注和通知他们需要更新或行动的有效方式.iOS 10有了新的通知,如新消息.商业信息和时间表的变化.在本教程中,我将向你展示如何使用通知在你的iOS应用程序,并且显示iOS 10引入了新特性.开发iOS 10推送通知你需要最新版本的Xcode,Xcode 8测试版,这些目前都是可下载的,在下载页面. 你可以去Github下载本教程的整个工程. 开始 在Xcode中启用推送通知是很容易的,但你需要几个步骤. 创建一个新的工程,给它起一个唯一的Bun

  • 轻松搞定iOS远程消息推送

    一.引言 IOS中消息的推送有两种方式,分别是本地推送和远程推送,本地推送在http://www.jb51.net/article/93602.htm这篇博客中有详细的介绍,这里主要讨论远程推送的流程与配置过程. 二.远程推送机制的原理 1.从一张很火的图说起 搜索IOS远程推送,你总能看到一张如下的流程示意图,因为这张图确实很火,所以我也将它引用在此: 这张图示意的很清晰,大致意思是这样:你的应用服务端将消息发送到apple的APNS服务器,APNS服务器将消息推送到指定的Iphone,最后由

随机推荐