iOS 개발 의 운동 이벤트 와 원 격 제어

이전에 우 리 는 터치 처리 와 제스처 인식 을 배 웠 습 니 다.사실은 이 두 가지 가 iOS 사건 에 속 하 는 터치 사건 입 니 다.오늘 우 리 는 iOS 사건 의 또 다른 두 가지 사건 을 배 워 보 겠 습 니 다.
운동 사건
운동 이 벤트 는 가속 기 를 통 해 촉발 되 며 터치 이벤트 와 마찬가지 로 UIResponder 클래스 의 대상 을 계승 해 야 운동 이 벤트 를 처리 할 수 있 습 니 다.
UIResponsder 운동 이벤트 처리 방법:

#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)canBecomeFirst Responser 방법 으로 YES 를 되 돌려 줍 니 다.
보기 컨트롤 러 의-(void)view Will Appear:(BOOL)animated 방법 에서 운동 컨트롤 러 의 become First Responsder 방법 을 호출 하여 컨트롤 을 표시 할 때 첫 번 째 응답 자가 되도록 합 니 다.
보기 컨트롤 러 의-(void)view Did Disappear:(BOOL)animated 방법 에서 운동 컨트롤 러 의 resignFirst Responsder 방법 을 호출 하여 컨트롤 이 표시 되 지 않 을 때 컨트롤 의 첫 번 째 응답 자 를 로그아웃 합 니 다.
실례:

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
운동 이벤트 실례 효과

2.원 격 제어 이벤트
iOS 원 격 제어 이 벤트 는 다른 원 격 장 치 를 통 해 실 행 됩 니 다(예:이어폰 제어 버튼).iOS 원 격 제어 이벤트 와 관련 된 것 은-(void)remoteControl Received WithEvent:(UIEvent*)이벤트 뿐 입 니 다.
원 격 제어 사건 을 감청 하 는 전제:
원 격 이벤트 수신,호출 시작
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
UI 컨트롤 역시 첫 번 째 응답 자가 되 어야 합 니 다[참고 운동 이벤트 사용]
그러나 보기 컨트롤 러 나 UIApplication 이 라면 첫 번 째 응답 자 를 요구 하지 않 았 습 니 다.
응용 프로그램 은 현재 오디 오 컨트롤 러 여야 합 니 다.
현재 iOS 7 에서 원 격 제어 권한 은 오디 오 제어 에 만 제 한 됩 니 다.

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
원 격 제어 실례 효과

이번 노트 에 많은 코드 를 붙 인 것 은 이 두 사건 의 사용 이 간단 하고 이론 지식 이 많 지 않 으 며 이론 만 말 해도 이해 하기 어렵 고 코드 를 붙 이 는 것 이 매우 직관 적 이기 때문이다.

좋은 웹페이지 즐겨찾기