zoukankan      html  css  js  c++  java
  • iOS开发UIEvent事件简介

    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                              = 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,//快进结束【操作:按耳机线控中间按钮两下到了快进的位置松开】
    };

    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() % 5+1;
        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(0, 480, [UIScreen mainScreen].bounds.size.width, 88)];
        view.backgroundColor = [UIColor yellowColor];
        view.alpha = 0.9;
        [self.view addSubview:view];
        
        //添加播放按钮
        _playButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _playButton.bounds = CGRectMake(0, 0, 50, 50);
        _playButton.center = CGPointMake(CGRectGetWidth(view.frame)/2,CGRectGetHeight(view.frame)/2);
        [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。

      

  • 相关阅读:
    hihoCoder #1176 : 欧拉路·一 (简单)
    228 Summary Ranges 汇总区间
    227 Basic Calculator II 基本计算器II
    226 Invert Binary Tree 翻转二叉树
    225 Implement Stack using Queues 队列实现栈
    224 Basic Calculator 基本计算器
    223 Rectangle Area 矩形面积
    222 Count Complete Tree Nodes 完全二叉树的节点个数
    221 Maximal Square 最大正方形
    220 Contains Duplicate III 存在重复 III
  • 原文地址:https://www.cnblogs.com/xianfeng-zhang/p/9469629.html
Copyright © 2011-2022 走看看