ios自用学习笔记-触摸事件与手势识别

     触摸事件与手势识别是ios中比较核心的功能,因为ios设备通常就只有5个实体按钮:音量大小,静音,开关与home键。因此了解、使用触摸事件与手势识别是学习ios的重点内容。


一、触摸事件

触摸事件主要有以下几个方法:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

从方法名称就能知道每个方法分别在什么时候执行。

需要注意的是触摸事件在ios中的事件传输机制。当发生触摸事件时,系统会判断触摸事件发生在哪一个view中,然后判断当前view是否实现了触摸事件的方法,如果没有,那么该事件就会传递到当前view的superview中,如果仍未实现,则继续向上传递,一直传递到application,最后还是没有实现,则丢弃该事件。

比如想实现一个跟随移动的小球,只需在小球的view里面添加如下代码即可:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint current = [touch locationInView:self.superview];
    self.center = current;
}
很简单的三行代码就实现来一个随手指移动的ui控件,是不是很神奇!

从上面可以看到方法传进了一个touches参数,这个参数包含了UITouch类,而UITouch类包含了如下信息:

1.window         触摸时所在的窗口

2.view               触摸时所在的view

3.tapcount       短时间内点击的次数

4.timestamp     触摸产生或变化的时间戳

5.phase           触摸周期内的各个状态

6.locationinview      取得在制定视图的位置

6.previouslocationinview 前一个位置


二、手势识别

在ios3.2过后苹果为我们封装了一些常用手势,这样就不需要我们自己写算法来判断用户手势了。在ios中有六种手势供我们使用:

UITapGestureRecognizer 点按手势

UIPinchGestureRecognizer 捏合手势

UIPanGestureRecognizer 拖动手势

UISwipeGestureRecognizer 轻扫手势(注意轻扫有四个方向,上下左右,需要分别设置)

UITRotationGestureRecognizer 旋转手势

UILongPressGestureRecognizer 长按手势

他们都是继承自UIGestureRecognizer,但是这个类本身是不能直接使用的。

属性:

@property(nonatomic,readonly)UIGestureRecognizerState state; 手势状态

@property(nonatomic,getter=isEnabled)BOOL enabled; 手势是否可用

@property(nonatomic,readonly)UIView *view; 触发手势的视图

@property(nonatomic)delaysTouchesBegan; 手势识别失败前是否执行触摸开始事件
常用方法:

-(void)addTarget:(id)target action:(SEL)action; 添加触摸执行事件

-(void)removeTarget:(id)target action:(SEL)action; 移除触摸执行事件

-(NSInteger)numberOfTouches; 触摸点的个数

-(CGPoint)locationInView:(UIView *)view; 触摸点在指定视图中的位置

-(CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView *)view; 触摸点相对于指定视图的位置

下面是一个向左轻扫的代码片段,展示了如何使用手势识别:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:swipeLeft];
}

-(void)swipe
{
    NSLog(@"YC");
}

触摸事件与手势识别还有很多地方值得研究,这篇文章就写到这里,以后等需要再继续研究。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是手势解锁的Demo实现过程: 1. 首先创建一个UIView的子类,作为手势解锁的主体视图,我们称之为`GestureLockView`。 2. 在`GestureLockView`中创建一个数组`circleArray`,用于存储手势解锁的圆点。 ``` @property (nonatomic, strong) NSMutableArray *circleArray; ``` 3. 在`GestureLockView`的`layoutSubviews`方法中,创建9个圆点,并加入到`circleArray`中。 ``` - (void)layoutSubviews { [super layoutSubviews]; CGFloat margin = (self.frame.size.width - 3 * kCircleSize) / 4.0; for (int i = 0; i < 9; i++) { CGFloat x = margin + (i % 3) * (margin + kCircleSize); CGFloat y = margin + (i / 3) * (margin + kCircleSize); CGRect frame = CGRectMake(x, y, kCircleSize, kCircleSize); GestureLockCircle *circle = [[GestureLockCircle alloc] initWithFrame:frame]; circle.tag = i + 1; [self addSubview:circle]; [self.circleArray addObject:circle]; } } ``` 4. 在`GestureLockView`中创建一个数组`selectedArray`,用于存储用户选择的圆点。 ``` @property (nonatomic, strong) NSMutableArray *selectedArray; ``` 5. 在`GestureLockView`中实现手势识别的方法`touchesMoved:withEvent:`,通过判断触摸点是否在圆点内来确定用户选择的圆点,并绘制用户选择的线条。 ``` - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView:self]; for (GestureLockCircle *circle in self.circleArray) { if (CGRectContainsPoint(circle.frame, point) && !circle.selected) { circle.selected = YES; [self.selectedArray addObject:circle]; break; } } self.currentPoint = point; [self setNeedsDisplay]; } ``` 6. 在`GestureLockView`中实现绘制方法`drawRect:`,根据用户选择的圆点绘制线条。 ``` - (void)drawRect:(CGRect)rect { if (self.selectedArray.count == 0) { return; } UIBezierPath *path = [UIBezierPath bezierPath]; path.lineWidth = kLineWidth; path.lineJoinStyle = kCGLineJoinRound; path.lineCapStyle = kCGLineCapRound; [[UIColor whiteColor] set]; for (int i = 0; i < self.selectedArray.count; i++) { GestureLockCircle *circle = self.selectedArray[i]; if (i == 0) { [path moveToPoint:circle.center]; } else { [path addLineToPoint:circle.center]; } } [path addLineToPoint:self.currentPoint]; [path stroke]; } ``` 7. 在`GestureLockView`中实现手势结束的方法`touchesEnded:withEvent:`,判断用户手势是否正确,并通过代理方法通知外部。 ``` - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSMutableString *password = [NSMutableString string]; for (GestureLockCircle *circle in self.selectedArray) { [password appendFormat:@"%ld", circle.tag]; } BOOL success = [password isEqualToString:self.password]; if (success) { for (GestureLockCircle *circle in self.selectedArray) { circle.selected = NO; } [self.selectedArray removeAllObjects]; [self setNeedsDisplay]; if (self.delegate && [self.delegate respondsToSelector:@selector(gestureLockView:didCompleteWithPassword:)]) { [self.delegate gestureLockView:self didCompleteWithPassword:password]; } } else { for (GestureLockCircle *circle in self.selectedArray) { circle.selected = NO; circle.error = YES; } [self.selectedArray removeAllObjects]; [self setNeedsDisplay]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kErrorDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ for (GestureLockCircle *circle in self.circleArray) { circle.error = NO; } [self setNeedsDisplay]; }); } } ``` 8. 在外部创建`GestureLockView`实例,并设置代理方法,实现手势解锁的逻辑。 ``` - (void)viewDidLoad { [super viewDidLoad]; GestureLockView *lockView = [[GestureLockView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenWidth)]; lockView.center = self.view.center; lockView.delegate = self; lockView.password = @"123456789"; [self.view addSubview:lockView]; } #pragma mark - GestureLockViewDelegate - (void)gestureLockView:(GestureLockView *)lockView didCompleteWithPassword:(NSString *)password { NSLog(@"password: %@", password); } ``` 至此,手势解锁的Demo已经完成了,你可以尝试在模拟器或真机上运行它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值