当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS开发之运动事件和远程控制

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

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

远程控制实例效果

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网