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開(kāi)始支持此事件)
    UIEventSubtypeMotionShake                       = 1,
    
    //遠(yuǎn)程控制子事件類型(從iOS4.0開(kāi)始支持遠(yuǎn)程控制事件)
    //播放事件【操作:停止?fàn)顟B(tài)下,按耳機(jī)線控中間按鈕一下】
    UIEventSubtypeRemoteControlPlay                 = 100,
    //暫停事件
    UIEventSubtypeRemoteControlPause                = 101,
    //停止事件
    UIEventSubtypeRemoteControlStop                 = 102,
    //播放或暫停切換【操作:播放或暫停狀態(tài)下,按耳機(jī)線控中間按鈕一下】
    UIEventSubtypeRemoteControlTogglePlayPause      = 103,
    //下一曲【操作:按耳機(jī)線控中間按鈕兩下】
    UIEventSubtypeRemoteControlNextTrack            = 104,
    //上一曲【操作:按耳機(jī)線控中間按鈕三下】
    UIEventSubtypeRemoteControlPreviousTrack        = 105,
    //快退開(kāi)始【操作:按耳機(jī)線控中間按鈕三下不要松開(kāi)】
    UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
    //快退停止【操作:按耳機(jī)線控中間按鈕三下到了快退的位置松開(kāi)】
    UIEventSubtypeRemoteControlEndSeekingBackward   = 107,
    //快進(jìn)開(kāi)始【操作:按耳機(jī)線控中間按鈕兩下不要松開(kāi)】
    UIEventSubtypeRemoteControlBeginSeekingForward  = 108,
    //快進(jìn)停止【操作:按耳機(jī)線控中間按鈕兩下到了快進(jìn)的位置松開(kāi)】
    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(@"搖動(dòng)開(kāi)始");
    
    //播放文件路徑
    NSString *pathStr = [[NSBundle mainBundle]pathForResource:@"59" ofType:@"m4a"];
    NSURL *sourURL = [NSURL fileURLWithPath:pathStr];
    //注冊(cè)系統(tǒng)音頻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(@"搖動(dòng)結(jié)束");
}
-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{
    if (event.subtype == UIEventSubtypeMotionShake) {
        NSLog(@"搖動(dòng)取消");
    }
}

RemoteControlEvents

//為了模擬一個(gè)真實(shí)的播放器,程序中我們啟用了后臺(tái)運(yùn)行模式,配置方法:在info.plist中添加UIBackgroundModes并且添加一個(gè)元素值為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:@"小蘋(píng)果" ofType:@"mp3"]]];
    [_player play];
}
#pragma mark =====3 線控
//配置方法:在info.plist中添加UIBackgroundModes并且添加一個(gè)元素值為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(@"單擊,再按下不放,松開(kāi)時(shí):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];//設(shè)置通知
}
//通知方法的實(shí)現(xiàn)
- (void)audioRouteChangeListenerCallback:(NSNotification*)notification
{
    
    NSDictionary *interuptionDict = notification.userInfo;
    NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    switch (routeChangeReason) {
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
            NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable");
            tipWithMessage(@"耳機(jī)插入");
            break;
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
            NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
            tipWithMessage(@"耳機(jī)拔出,停止播放操作");
            break;
        case AVAudioSessionRouteChangeReasonCategoryChange:
            // called at start - also when other audio wants to play
            tipWithMessage(@"AVAudioSessionRouteChangeReasonCategoryChange");
            break;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,660評(píng)論 5 6
  • 做為一個(gè)2點(diǎn)一線的技術(shù)人員,每天不是上班,還是上班,一天工作12~14個(gè)小時(shí),連感嘆的時(shí)間都沒(méi)有,對(duì)于一些朋友圈天...
    那一抹的涼閱讀 280評(píng)論 0 0
  • 張德倫詩(shī)詞 武當(dāng)行(三首) 大岳蜿蜒八百里,自生靈氣九千年。 擎天一柱驚云破,三界名山齊拱仙。 問(wèn)道武當(dāng)?shù)啦煌?,?..
    德惠陳旭閱讀 444評(píng)論 0 1
  • 我見(jiàn)到衰老的青春了 這些似桃花開(kāi)過(guò)的句子 夾雜在溫暖又陸離的墮落里 它們有嘲笑我還在痛苦的活著 上個(gè)世紀(jì)的青春,純...
    詩(shī)人金子閱讀 196評(píng)論 0 0

友情鏈接更多精彩內(nèi)容