1.iOS中的事件分发


Demo:如果要摇一摇之类的应用,就可以使用运动事件进行处理,代码如下所示
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController () {
BOOL acceptNextShake;
}
@end
@implementation ViewController
// 封装一个播放段音频的方法
- (void)playSoundEffect:(NSString *)name withCallback:(void (*)(SystemSoundID, void *)) callback {
NSString *audioFile = [[NSBundle mainBundle] pathForResource:name ofType:nil];
NSURL *fileUrl = [NSURL fileURLWithPath:audioFile];
SystemSoundID soundID;
// 在系统中创建一个音效对象并获得其唯一ID
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
// 注册在播放完之后执行的回调函数
// 第二个和第三个参数跟循环播放有关
// 第五个参数是指向传给回调函数的数据的指针
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, callback, NULL);
// 播放音效
AudioServicesPlaySystemSound(soundID);
// 播放音效并震动
// AudioServicesPlayAlertSound(soundID);
}
// 摇一摇开始播放金币掉下的短音频
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if(acceptNextShake) {
acceptNextShake = NO;
[self playSoundEffect:@"4679.mp3" withCallback:nil];
// 阻止播放音效文件5秒钟
dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(5);
acceptNextShake = YES;
});
}
}
- (void)viewDidLoad {
[super viewDidLoad];
acceptNextShake = YES;
}
@end

请看下面的例子:
#import <UIKit/UIKit.h>
@interface CDMyView : UIView
@property (nonatomic, copy) NSString *name;
@end
#import "CDMyView.h"
@implementation CDMyView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"%@", event);
NSLog(@"%@", self.name);
}
@end
#import <UIKit/UIKit.h>
@interface CDThyView : UIView
@property (nonatomic, copy) NSString *name;
@end
#import "CDThyView.h"
@implementation CDThyView
@end
#import "ViewController.h"
#import "CDMyView.h"
#import "CDThyView.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CDMyView *view1 = [[CDMyView alloc] initWithFrame:CGRectMake(50, 50, 275, 500)];
view1.backgroundColor = [UIColor redColor];
view1.name = @"view1";
CDMyView *view2 = [[CDMyView alloc] initWithFrame:CGRectMake(20, 20, 230, 200)];
view2.backgroundColor = [UIColor orangeColor];
view2.name = @"view2";
CDThyView *view3 = [[CDThyView alloc] initWithFrame:CGRectMake(20, 240, 230, 320)];
view3.backgroundColor = [UIColor yellowColor];
view3.name = @"view3";
CDMyView *view4 = [[CDMyView alloc] initWithFrame:CGRectMake(20, 20, 100, 150)];
view4.backgroundColor = [UIColor greenColor];
view4.name = @"view4";
CDMyView *view5 = [[CDMyView alloc] initWithFrame:CGRectMake(20, 40, 240, 60)];
view5.backgroundColor = [UIColor cyanColor];
view5.name = @"view5";
[self.view addSubview:view1];
[view1 addSubview:view2];
[view1 addSubview:view3];
[view2 addSubview:view4];
[view4 addSubview:view5];
}
@end
试着点击屏幕上圈出来的几个区域,看看会发生什么并解释为什么


点击查看响应链具体http://www.jianshu.com/p/5fc46fb91e80
2.iOS中的手势操作



#import "ViewController.h"
@interface ViewController () <UIGestureRecognizerDelegate> {
UIImageView *imageView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
// 创建UIImage对象并获得其尺寸
UIImage *image = [UIImage imageNamed:@"Dudu.jpg"];
CGSize imageSize = image.size;
// 用UIImage创建UIImageView并执行其位置和尺寸
imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = self.view.bounds;
imageView.frame = CGRectMake((rect.size.width - imageSize.width) / 2, (rect.size.height - imageSize.height) / 2, imageSize.width, imageSize.height);
// 设置允许用户交互行为
imageView.userInteractionEnabled = YES;
// 创建捏合手势识别器并添加到上面的UIImageView上
UIPinchGestureRecognizer *r1 = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(doPinch:)];
[imageView addGestureRecognizer:r1];
// 给手势识别器绑定委托
r1.delegate = self;
// 创建旋转手势识别器并添加到上面的UIImageView上
UIRotationGestureRecognizer *r2 = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(doRotate:)];
[imageView addGestureRecognizer:r2];
// 给手势识别器绑定委托
r2.delegate = self;
// 连续3次点击删除图片
UITapGestureRecognizer *r3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doRemove)];
// 设置需要3次点击
r3.numberOfTapsRequired = 3;
[imageView addGestureRecognizer:r3];
// 添加一个长按手势识别器
UILongPressGestureRecognizer *r4 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(doAddBall:)];
r4.minimumPressDuration = 1; // 至少按住1秒钟
[self.view addGestureRecognizer:r4];
[self.view addSubview:imageView];
}
- (void) doPinch:(UIPinchGestureRecognizer *) sender {
// 通过放射变换实现图片缩放
imageView.transform = CGAffineTransformScale(imageView.transform, sender.scale, sender.scale);
// 防止效果叠加
sender.scale = 1;
}
- (void) doRotate:(UIRotationGestureRecognizer *) sender {
// 通过放射变换实现图片旋转
imageView.transform = CGAffineTransformRotate(imageView.transform, sender.rotation);
// 防止效果叠加
sender.rotation = 0;
}
- (void) doRemove {
[imageView removeFromSuperview];
}
- (void) doAddBall:(UILongPressGestureRecognizer *) sender {
// 对手势做一个状态判断:只有在刚识别到长按手势时才绘制篮球
if(sender.state == UIGestureRecognizerStateBegan) {
// 获取长按的位置在屏幕上对应的点
CGPoint point = [sender locationInView:self.view];
UIView *tempView = [[[NSBundle mainBundle] loadNibNamed:@"CDBallView" owner:self options:nil] lastObject];
// 将手指按下的位置作为新视图的中心点
tempView.center = point;
[self.view addSubview:tempView];
}
}
// 同时支持多个手势操作的回调方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
// 有没有什么情况只能支持一个手势呢?
return YES;
}
@end
上面的例子中使用的XIB文件如下图所示:

手势识别器也可以设置委托(UIGestureRecognizerDelegate)来支持下面的操作:
1.两个手势可以同时被认可:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
2.手势与控件冲突:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
网友评论