swipe Rotation Pan Press Tap Pinch
1.
swipe手势
简单代码:
_mySwipeGR = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipes:)]; //设定轻扫手势方向: //只检测符合设定的这个方向的手势 _mySwipeGR.direction = UISwipeGestureRecognizerDirectionLeft; //设定轻扫手势手指数: //必须需要的手指数 _mySwipeGR.numberOfTouchesRequired = 1; //添加到需要手势的View [self.view addGestureRecognizer:_mySwipeGR];
更多设置详读开发文档
2.Rotation手势
对继承自 UIView 的 UI 元素进行旋转,你可以将旋转手势识别器的 rotation 属性传 递给 CGAffineTransformMakeRotation 方法,以制作一个仿射转场。如下面的实例所示
- (void)ViewRotation{ _helloWorldLabel = [[UILabel alloc]initWithFrame:CGRectZero]; _helloWorldLabel.text = @"Hello World!"; _helloWorldLabel.font = [UIFont systemFontOfSize:16.0f]; [_helloWorldLabel sizeToFit]; _helloWorldLabel.center = self.view.center; [self.view addSubview:_helloWorldLabel]; _rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(handleRotation:)]; [self.view addGestureRecognizer:_rotationGestureRecognizer]; }
- (void)handleRotation:(UIRotationGestureRecognizer *)paramSender{ if (_helloWorldLabel == nil) { return; } //设置label的仿射旋转:随时变化角度 _helloWorldLabel.transform = CGAffineTransformMakeRotation(self.rotationAngleInRotations + paramSender.rotation); if (paramSender.state == UIGestureRecognizerStateEnded) { self.rotationAngleInRotations += paramSender.rotation; } }
3.Pan 手势
Pan 手势是手指在屏幕上连续的移动。也就是说 pan 手势识别器的目标方法会被重复的调用(从识别处理的开始直到结束)
例子:
- (void)ViewPan{ CGRect labelFrame = CGRectMake(0, 0, 150, 100); panLabel = [[UILabel alloc]initWithFrame:labelFrame]; panLabel.text = @"Hello World"; panLabel.backgroundColor = [UIColor blackColor]; panLabel.textColor = [UIColor whiteColor]; panLabel.textAlignment = NSTextAlignmentCenter; //必须打开交互开关 panLabel.userInteractionEnabled = YES; [self.view addSubview:panLabel]; //给panlabel添加拖拽手势 UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePanGestures:)]; //设置拖拽时需要的最大最小手指数 panGR.minimumNumberOfTouches = 1; panGR.maximumNumberOfTouches = 1; [panLabel addGestureRecognizer:panGR]; }
一般当拖动手势产生的时候会顺序的经过如下几个状态。
1)UIGestureRecognizerStateBegan 2)UIGestureRecognizerStateChanged 3)UIGestureRecognizerStateEnde
我们一般会实现手势识别时的处理方法,如下的代码,将会实现利用手指来移动屏幕中间的一个标签
- (void)handlePanGestures:(UIPanGestureRecognizer *)paramSender{ if (paramSender.state != UIGestureRecognizerStateEnded && paramSender.state != UIGestureRecognizerStateFailed) { //为了能达到移动我们屏幕中的标签,我们需要获取手指在屏幕中的坐标, 并不是在标签中的坐标。 CGPoint location = [paramSender locationInView:paramSender.view.superview]; paramSender.view.center = location; } }
通过使用 locationInView 这个方法,来获取到我们手势的坐标,为了能够捕获到多个手 指的位置,我们就需要使用 locationOfTouch:inView: 这个方法。然后通过使用 UIPanGestureRecognizer 这 个 对 象 的 minimumNumberOfTouches 和 maximumNumberOfTouches 参数。你就可以在同一个时间来捕获多个手指的拖拽的动作了。
4.Press 手势
iOS SDK 提供了一个类来监听长按手势事件,这个类就是 UILongTapGestureRecognizer,当用户用一个手指或者多个手指长按在一个 UIView 上时,会触发长按事件 ,这个类中的几个重要属性:
numberOfTapsRequired
这个属性就保存了用户点击的次数,当这个手势动作触发之前,并没有一个手势是在屏幕是上的,当第一次把手指点击在屏幕上,然后拿开,这个动作可以称为一次点击时间。
numberOfTouchesRequired
这个属性保存了有多少个手指点击了屏幕,因此你要确保你每次的点击手指数目是一样 的,默认值是为 0.
allowableMovement
用于指定可以移动的最大 pixels。
minimumPressDuration
这个参数表示,两次点击之间间隔的时间长度。
- (void) viewPress{ dummyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; dummyButton.frame = CGRectMake(100.0f, 150.0f, 72.0f, 37.0f); dummyButton.titleLabel.text = @"长按屏幕"; [self.view addSubview:dummyButton]; //创建长按手势 UILongPressGestureRecognizer *longPressGR = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongPressGestures:)]; //设置必须需要长按的手指数 longPressGR.numberOfTouchesRequired = 2; //按下去后打破长按手势的移动距离 默认为10 longPressGR.allowableMovement = 10.0f; //最短按的秒数 longPressGR.minimumPressDuration = 1.0f; [self.view addGestureRecognizer:longPressGR]; } - (void)handleLongPressGestures:(UILongPressGestureRecognizer *)paramSender{ CGPoint touchPoint1 = [paramSender locationOfTouch:0 inView:paramSender.view]; CGPoint touchPoint2 = [paramSender locationOfTouch:1 inView:paramSender.view]; CGFloat midPointX = (touchPoint1.x + touchPoint2.x)/2.0f; CGFloat midPointY = (touchPoint1.y + touchPoint2.y)/2.0f; CGPoint midPoint = CGPointMake(midPointX, midPointY); dummyButton.center = midPoint; }
一个比较典型的用手指来长时间的点击屏幕就是地图的这个应用,当你看不同地方的时候,通过你的手指按住屏幕,然后不要松手,长久按下去,那么不过一会就会有一个锚点标记在地图上
5.tap手势
轻击手势:检测捕获用户点击了屏幕的事件
- (void)viewTap{ UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTaps:)]; tapGR.numberOfTouchesRequired = 2;//默认也为1 tapGR.numberOfTapsRequired = 3;//需要点3次才能触发事件 [self.view addGestureRecognizer:tapGR]; } - (void)handleTaps:(UITapGestureRecognizer *)paramSender{ NSUInteger touchCounter = 0; for (touchCounter = 0; touchCounter < paramSender.numberOfTouchesRequired; touchCounter++) { CGPoint touchPoint = [paramSender locationOfTouch:touchCounter inView:paramSender.view]; NSLog(@"Touch #%lu:%@",(unsigned long)touchCounter + 1,NSStringFromCGPoint(touchPoint)); } }
在这段代码中,我们通过两个手指来点击屏幕的手势动作,获取每一次点击的位置,因 此当我们运行这段代码,并且手势动作完成之后,我们会得到我们点击的屏幕位置。
Touch #1:{221.5, 448}
Touch #2:{153.5, 219}
6.pinch手势
通过捏合手势动作可以很轻松的来改变视图元素的一个比例,例如,我们在通过 Safari 浏览器打开网页的时候,有时间为了能够更清晰的看到其中的一些文字,那么我们就需要放 大我们的屏幕了,有时候我们又需要缩放页面。
手势的动作状态有如下三种,一般是按照顺序来进行转换的。
1). UIGestureRecognizerStateBegan
2). UIGestureRecognizerStateChanged
3). UIGestureRecognizerStateEnded
一旦捏合手势动作产生了之后,我们就需要在捕获的事件中进行一个页面调整。其中有两个比较重要的变量 scale 和 velocity,前者是一个比例范围,后者是一个变化速率的,也就是说每次变化的一个像素点。
一般设置代码如下 :
- (void)viewPinch{ CGRect labelRect = CGRectMake(0.0f, 250.0f, 200.0f, 200.0f); myBlackLabel = [[UILabel alloc]init]; myBlackLabel.backgroundColor = [UIColor blackColor]; myBlackLabel.frame = labelRect; myBlackLabel.userInteractionEnabled = YES; [self.view addSubview:myBlackLabel]; UIPinchGestureRecognizer *pinchGR = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinches:)]; [myBlackLabel addGestureRecognizer:pinchGR]; } - (void)handlePinches:(UIPinchGestureRecognizer*)paramSender{ if (paramSender.state == UIGestureRecognizerStateEnded) { currentScale = paramSender.scale; }else if (paramSender.state == UIGestureRecognizerStateBegan && currentScale != 0.0f){ paramSender.scale = currentScale; } //NAN Not A Number就是代表不是一个数据 if (paramSender.scale != NAN && paramSender.scale != 0.0) { //Return a transform which scales by `(sx, sy)': 捏合时x/y方向的该变量相同,所以都填的paramSender.scale paramSender.view.transform = CGAffineTransformMakeScale(paramSender.scale, paramSender.scale); } }
由于 scale 这个属性的值是每次都在变的,所以我们需要用另外一个变量来保存当前的 一个 scale 的值,这个变量叫做 currentScale,这样我们就行进行一个缩小,变大的视图效果了