UIEvent Class

UIEvent
A UIEvent object (or, simply, an event object) represents an event in iOS. There are three general types of event: **touch events, motion events, and remote-control events ** Remote-control events allow a responder object to receive commands from an external accessory or headset so that it can manage manage audio and video—for example, playing a video or skipping to the next audio track. Motion events were introduced in iOS 3.0 and remote-control events in iOS 4.0.

Overview
A touch type of event object contains one or more touches (that is, finger gestures on the screen) that have some relation to the event. A touch is represented by a UITouch object. When a touch event occurs, the system routes it to the appropriate responder and passes in the UIEvent object in a message invoking a UIResponder method such as touchesBegan:withEvent:. The responder can then evaluate the touches for the event or for a particular phase of the event and handle them appropriately. The methods of UIEvent allow you to obtain all touches for the event (allTouches) or only those for a given view or window (touchesForView: or touchesForWindow:). It can also distinguish an event object from objects representing other events by querying an object for the time of its creation (timestamp).
A UIEvent object representing a touch event is persistent throughout a multi-touch sequence; UIKit reuses the same UIEvent instance for every event delivered to the application. You should never retain an event object or any object returned from an event object. If you need to keep information from an event around from one phase to another, you should copy that information from the UITouch or UIEvent object.
You can obtain event types and subtypes from the type and subtype properties. UIEvent defines event types for touch, motion, and remote-control events. It also defines a motion subtype for "shake” events and a series of subtype constants for remote-control events, such as “play” and “previous track.” The first responder or any responder in the responder chain implements the motion-related methods of UIResponder (such as motionBegan:withEvent:) to handle shaking-motion events. To handle remote-control events, a responder object must implement the remoteControlReceivedWithEvent: method of UIResponder.
The touchesForGestureRecognizer: method, which was introduced in iOS 3.2, allows you to query a gesture-recognizer object (an instance of a subclass of UIGestureRecognizer) for the touches it is currently handling.

typedef NS_ENUM(NSInteger, UIEventType) {
    UIEventTypeTouches,
    UIEventTypeMotion,
    UIEventTypeRemoteControl,
    UIEventTypePresses NS_ENUM_AVAILABLE_IOS(9_0),
};

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,
};

@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;
@property(nonatomic, readonly, nullable) NSSet <UITouch *> *allTouches;
- (nullable NSSet <UITouch *> *)touchesForWindow:(UIWindow *)window;
- (nullable NSSet <UITouch *> *)touchesForView:(UIView *)view;
- (nullable NSSet <UITouch *> *)touchesForGestureRecognizer:(UIGestureRecognizer *)gesture NS_AVAILABLE_IOS(3_2);

// An array of auxiliary UITouch’s for the touch events that did not get delivered for a given main touch. This also includes an auxiliary version of the main touch itself.
- (nullable NSArray <UITouch *> *)coalescedTouchesForTouch:(UITouch *)touch NS_AVAILABLE_IOS(9_0);

// An array of auxiliary UITouch’s for touch events that are predicted to occur for a given main touch. These predictions may not exactly match the real behavior of the touch as it moves, so they should be interpreted as an estimate.
- (nullable NSArray <UITouch *> *)predictedTouchesForTouch:(UITouch *)touch NS_AVAILABLE_IOS(9_0);

Shake to play systemSound using AudioToolBox.framework

static void AudioServicesSystemSoundCompletionCall(SystemSoundID ssID, void* __nullable clientData){
    NSLog(@"声音播放完成");
}
-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{
    NSLog(@"摇动开始");
    
    //播放文件路径
    NSString *pathStr = [[NSBundle mainBundle]pathForResource:@"59" ofType:@"m4a"];
    NSURL *sourURL = [NSURL fileURLWithPath:pathStr];
    //注册系统音频ID
    SystemSoundID soundId;
    
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)sourURL, &soundId);
//    AudioServicesPlaySystemSoundWithCompletion(soundId, ^{
//        AudioServicesDisposeSystemSoundID(soundId);
//    });
    //or
    AudioServicesAddSystemSoundCompletion(soundId, NULL, NULL, AudioServicesSystemSoundCompletionCall, (__bridge void *)self);
    AudioServicesPlaySystemSound(soundId);
}


-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{
    NSLog(@"摇动结束");
}
-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{
    if (event.subtype == UIEventSubtypeMotionShake) {
        NSLog(@"摇动取消");
    }
}

RemoteControlEvents

//为了模拟一个真实的播放器,程序中我们启用了后台运行模式,配置方法:在info.plist中添加UIBackgroundModes并且添加一个元素值为audio。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    if(![[AVAudioSession sharedInstance] setActive:YES error:nil])
    {
        NSLog(@"Failed to set up a session.");
    }
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

    // Override point for customization after application launch.
    return YES;
}
- (void)viewDidLoad {
    [super viewDidLoad];
      _player = [[AVPlayer alloc]initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"小苹果" ofType:@"mp3"]]];
    [_player play];
}
#pragma mark =====3 线控
//配置方法:在info.plist中添加UIBackgroundModes并且添加一个元素值为audio。
-(BOOL)canBecomeFirstResponder{
    return YES;
}
-(void)remoteControlReceivedWithEvent:(UIEvent *)event{
    
    if (event.type == UIEventTypeRemoteControl) {
        switch (event.subtype) {
            case UIEventSubtypeRemoteControlPlay:{
                NSLog(@"play---------");

            }break;
            case UIEventSubtypeRemoteControlPause:{
                NSLog(@"Pause---------");
            }break;
            case UIEventSubtypeRemoteControlStop:{
                NSLog(@"Stop---------");
            }break;
            case UIEventSubtypeRemoteControlTogglePlayPause:{
                //单击暂停键:103
                NSLog(@"单击暂停键:103");
                static int a = 0;
                a++;
                if (a%2 == 1) {
                    [_player pause];
                }else{
                    [_player play];
                }
            }break;
            case UIEventSubtypeRemoteControlNextTrack:{
                //双击暂停键:104
                NSLog(@"双击暂停键:104");
            }break;
            case UIEventSubtypeRemoteControlPreviousTrack:{
                NSLog(@"三击暂停键:105");
            }break;
            case UIEventSubtypeRemoteControlBeginSeekingForward:{
                NSLog(@"单击,再按下不放:108");
            }break;
            case UIEventSubtypeRemoteControlEndSeekingForward:{
                NSLog(@"单击,再按下不放,松开时:109");
            }break;
            default:
                break;
        }
    }
}
    

Insert earphone or pull out headphones

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(audioRouteChangeListenerCallback:)   name:AVAudioSessionRouteChangeNotification object:nil];//设置通知
}
//通知方法的实现
- (void)audioRouteChangeListenerCallback:(NSNotification*)notification
{
    
    NSDictionary *interuptionDict = notification.userInfo;
    NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    switch (routeChangeReason) {
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable");
            tipWithMessage(@"耳机插入");
            break;
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
            tipWithMessage(@"耳机拔出,停止播放操作");
            break;
        case AVAudioSessionRouteChangeReasonCategoryChange:
            // called at start - also when other audio wants to play
            tipWithMessage(@"AVAudioSessionRouteChangeReasonCategoryChange");
            break;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的阅读 13,429评论 5 6
  • 做为一个2点一线的技术人员,每天不是上班,还是上班,一天工作12~14个小时,连感叹的时间都没有,对于一些朋友圈天...
    那一抹的凉阅读 249评论 0 0
  • 张德伦诗词 武当行(三首) 大岳蜿蜒八百里,自生灵气九千年。 擎天一柱惊云破,三界名山齐拱仙。 问道武当道不同,道...
    德惠陳旭阅读 395评论 0 1
  • 我见到衰老的青春了 这些似桃花开过的句子 夹杂在温暖又陆离的堕落里 它们有嘲笑我还在痛苦的活着 上个世纪的青春,纯...
    诗人金子阅读 174评论 0 0