美文网首页iOS Developer - Tipsios开发笔记iOS Developer
iOS学习笔记07-运动事件和远程控制

iOS学习笔记07-运动事件和远程控制

作者: 执着丶执念 | 来源:发表于2016-03-25 16:15 被阅读613次

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

    你没有看错,这里说的运动事件,只是摇晃一下手机而已,所以只有运动开始、运动结束、运动取消,无法取得运动过程中的运动速度、运动方向等数据,这些需要另外的框架去实现,我们可以理解这里的运动时间为 “摆动事件”

    监听运动事件前提:
    1. 监听对象必须成为第一响应者,控件需要- (BOOL)canBecomeFirstResponder方法返回YES
    1. 在视图控制器的- (void)viewWillAppear:(BOOL)animated方法中调用运动控件的becomeFirstResponder方法,使控件显示时成为第一响应者
    2. 在视图控制器的- (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

    监听远程控制事件的前提:
    1. 启动远程事件接收,调用
      [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    1. UI控件同样要求必须成为第一响应者【使用参考运动事件】
      但如果是视图控制器或UIApplication,就没有要求成为第一响应者
    2. 应用程序必须是 当前音频额控制者
    目前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-运动事件和远程控制

      本文链接:https://www.haomeiwen.com/subject/qhfdlttx.html