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
원 격 제어 실례 효과이번 노트 에 많은 코드 를 붙 인 것 은 이 두 사건 의 사용 이 간단 하고 이론 지식 이 많 지 않 으 며 이론 만 말 해도 이해 하기 어렵 고 코드 를 붙 이 는 것 이 매우 직관 적 이기 때문이다.