(转)UIPanGestureRecognizer
UIPanGestureRecognizer是UIGestureRecognizer类的一个扩展类,其扩展类有UITapGestureRecognizer,UIPinchGestureRecognizer,UIRotationGestureRecognizer,UISwipeGestureRecognizer,UIPanGestureRecognizer,UILongPressGestureRecognizer。
借助这些类,可以实现UIView对象的一些操作如对象放大缩小,移动,旋转,滑动,轻击等。再也不用去重写UIView的touchBegin等方法来实现这些功能。
知识点:
UIGestureRecognizer是一个定义基本手势的抽象类,具体什么手势,在以下子类中包含:
1、拍击UITapGestureRecognizer (任意次数的拍击)
2、向里或向外捏UIPinchGestureRecognizer (用于缩放)
3、摇动或者拖拽UIPanGestureRecognizer (拖动)
4、擦碰UISwipeGestureRecognizer (以任意方向)
5、旋转UIRotationGestureRecognizer (手指朝相反方向移动)
6、长按UILongPressGestureRecognizer (长按)
这些操作的目的都是用来修改UIView对象的frame,center,bounds属性,还有一个Transform属性。
我写了一个例子,在UIView和UITableView上分别添加UIPanGestureRecognizer,实现两个对象在手指按住对象于屏幕中拖动的效果。
声明一个UIPanGestureRecognizer对象,添加到UIView对象上去。UIView类有这样的方法用来动态添加和删除UIPanGestureRecognizer对象。
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[testPanView addGestureRecognizer:panRecognizer];
UIView管理手势识别器的方法有:
– addGestureRecognizer:
– removeGestureRecognizer:
gestureRecognizers property
– gestureRecognizerShouldBegin:
我在viewDidAppear:方法中,动态添加视图和手势识别器。然后,实现识别器需要操作的两个方法,用来移动视图对象。
在这两个方法中最终的方法是这个 CGPoint translatedPoint = [recognizer translationInView:self.view];
每一次拖动操作状态,都会获取到translatedPoint,从开始到结束。它是一个绝对值,可以看着在”self.view“对应的坐标体系中,拖动的视图对象center的移动开始和结束的点差。
最简单的处理过程是这样:
CGPoint translatedPoint = [recognizer translationInView:self.view];
CGFloat x = recognizer.view.center.x + translatedPoint.x;
CGFloat y = recognizer.view.center.y + translatedPoint.y;
recognizer.view.center = CGPointMake(x, y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
首先获取到移动点的值,然后算一下视图的center值,相加一下,就得到在self.view坐标体系中,视图该移动到那个center上,一次结束就清零一次。
因为拖动操作持续进行,所以,这个过程会持续执行。
稍微复杂点的处理过程,会捕获到拖动开始,移动,结束等几个状态下的translatedPoint的值。然后做一下逻辑处理,如视图不能溢出self.view的坐标系中,如在结束时会根据方向自动滑动到某个位置。可以在handlePan2:方法中找到这些逻辑的实现代码。
- (void)viewDidAppear:(BOOL)animated
{
NSLog(@" viewDidAppear is at %@.", [NSDate date]);
UIImage *image = [UIImage imageNamed:@"5.jpg"];
testPanView = [[UIView alloc] initWithFrame:CGRectMake(18, 11, 100, 100)];
UIImageView *imageview = [[UIImageView alloc] initWithFrame:[testPanView frame]];
[imageview setImage:image];
[testPanView addSubview:imageview];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[testPanView addGestureRecognizer:panRecognizer];
[self.view addSubview:testPanView];
testPanTableView = [[UITableView alloc] initWithFrame:CGRectMake(118, 121, 100, 100) style:UITableViewStylePlain];
UIPanGestureRecognizer *panRecognizer2 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan2:)];
[panRecognizer2 setMinimumNumberOfTouches:1];
[panRecognizer2 setMaximumNumberOfTouches:1];
[panRecognizer2 setDelegate:self];
[testPanTableView addGestureRecognizer:panRecognizer2];
[self.view addSubview:testPanTableView];
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
CGPoint translatedPoint = [recognizer translationInView:self.view];
NSLog(@"gesture translatedPoint is %@", NSStringFromCGPoint(translatedPoint));
CGFloat x = recognizer.view.center.x + translatedPoint.x;
CGFloat y = recognizer.view.center.y + translatedPoint.y;
recognizer.view.center = CGPointMake(x, y);
NSLog(@"pan gesture testPanView moving is %@,%@", NSStringFromCGPoint(recognizer.view.center), NSStringFromCGRect(recognizer.view.frame));
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
- (void)handlePan2:(UIPanGestureRecognizer *)recognizer
{
// NSLog(@"gesture translatedPoint xxoo xxoo");
CGPoint translatedPoint = [recognizer translationInView:self.view];
if ([(UIPanGestureRecognizer *)recognizer state] == UIGestureRecognizerStateBegan) {
firstX = recognizer.view.center.x;
firstY = recognizer.view.center.y;
NSLog(@"self.view bounds is %@", NSStringFromCGRect(self.view.bounds));
NSLog(@"pan gesture testPanView begin is %@,%@", NSStringFromCGPoint([recognizer view].center), NSStringFromCGRect([recognizer view].frame));
}
if ([(UIPanGestureRecognizer *)recognizer state] == UIGestureRecognizerStateChanged) {
CGFloat x = firstX + translatedPoint.x;
CGFloat y = firstX + translatedPoint.y;
if (x < recognizer.view.width / 2.0) {
x = recognizer.view.width / 2.0;
} else if (x + recognizer.view.width / 2.0 > self.view.width) {
x = self.view.width - recognizer.view.width / 2.0;
}
if (y < recognizer.view.height / 2.0) {
y = recognizer.view.height / 2.0;
} else if (y + recognizer.view.height / 2.0 > self.view.height) {
y = self.view.height - recognizer.view.height / 2.0;
}
NSLog(@"gesture translatedPoint moving is %@", NSStringFromCGPoint(translatedPoint));
recognizer.view.center = CGPointMake(x, y);
}
if (([(UIPanGestureRecognizer *)recognizer state] == UIGestureRecognizerStateEnded) || ([(UIPanGestureRecognizer *)recognizer state] == UIGestureRecognizerStateCancelled)) {
CGFloat x = recognizer.view.center.x;
CGFloat y = recognizer.view.center.y;
if (x > firstX) {
x = self.view.width - recognizer.view.width / 2.0;
} else {
x = recognizer.view.width / 2.0;
}
if (y > firstY) {
y = self.view.height - recognizer.view.height / 2.0;
} else {
y = recognizer.view.height / 2.0;
}
CGFloat velocityX = (0.2 *[recognizer velocityInView:self.view].x);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:ABS(velocityX * 0.00002 + 0.2)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
recognizer.view.center = CGPointMake(x, y);
[UIView commitAnimations];
NSLog(@"gesture translatedPoint end is %@", NSStringFromCGPoint(translatedPoint));
NSLog(@"pan gesture testPanView end is %@,%@", NSStringFromCGPoint([recognizer view].center), NSStringFromCGRect([recognizer view].frame));
}
}
(转)UIPanGestureRecognizer的更多相关文章
- 拖拽手势和清扫手势冲突时(UIPanGestureRecognizer和UISwipeGestureRecognizer冲突时)
故事发生在这样的情境上:给整个控制器添加了一个拖拽手势,然后又在控制上的每个Cell上加了左滑清扫手势,然后问题来了:只有拖拽手势起作用,而左滑手势没有效果了,然后怎么解决这个问题呢!先上图: 当给整 ...
- 如何判断UIPanGestureRecognizer的拖动方向
最近做一个项目,需要用到UIPanGestureRecognizer做一个侧滑菜单,需求是不能向右侧拖动(点击按钮右滑),但可以向左侧手势拖动收回:于是需要判断拖动的方向,百度了一下,网上大部分的答案 ...
- IOS开发之进阶篇第一章 - 姿势识别器UIPanGestureRecognizer
今天讲一下姿势识别器,UIGestureRecognizer这个是抽象类 1.拍击UITapGestureRecognizer (任意次数的拍击) 2.向里或向外捏UIPinchGestureReco ...
- iOS开发 UIPanGestureRecognizer手势抽象类
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@sel ...
- UIPanGestureRecognizer中translationInView的理解
原因是在破船大牛的blog上面看到了一个demo #import <UIKit/UIKit.h> @interface ViewController : UIViewController ...
- UIPanGestureRecognizer
http://blog.csdn.net/huifeidexin_1/article/details/8282035 UIGestureRecognizer是一个定义基本手势的抽象类,具体什么手势,在 ...
- uiscrollview上的 uipangesturerecognizer冲突
最近在tableview里的cell imageview加了个 uipangesturerecognizer发现优先滚动imageview,往上拖的时候,tableView不响应滚动了,原来是tabl ...
- UIPanGestureRecognizer的使用
UIGestureRecognizer是一个定义基本手势的抽象类,具体什么手势,在以下子类中包含: 1.拍击UITapGestureRecognizer (任意次数的拍击) 2.向里或向外捏 ...
- UIPanGestureRecognizer 拖动TableView改变其高度
需求:项目中要求tableView的高度随着手拖动的位置而改变如下图: 关键代码如下: - (void)viewDidLoad{ panGestureRecognizer = [[UIPanGestu ...
- UIPanGestureRecognizer判断滑动的方向
.h文件 CGFloat const gestureMinimumTranslation = 20.0 ; typedef enum : NSInteger { kCameraMoveDirectio ...
随机推荐
- [題解](并查集)luogu_P2391 白雪皚皚
今天被老師留的作業搞死了,全是裸的水題,難題就那麼兩道我還沒寫......,狗屎 1.倒序處理,每個點至多會被更新一次 2.所以要做的就是快速找到下一個不同顏色的點, 3.然而不知道怎麼就 想到用并查 ...
- 爬虫scrapy框架之CrawlSpider
爬虫scrapy框架之CrawlSpider 引入 提问:如果想要通过爬虫程序去爬取全站数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模 ...
- 【loj10064】黑暗城堡
#10064. 「一本通 3.1 例 1」黑暗城堡 内存限制:512 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 1bentong 提交 ...
- js操作表格
js 操作table: insertRow(),deleteRow(),insertCell(),deleteCell()方法 表格有几行: var trCnt = table.rows.length ...
- selenium登录 京东滑动验证码
京东的滑动验证码在页面上是没有原图的,所有我是用ps把他们拼成一个的. from selenium import webdriver from selenium.webdriver import Ac ...
- freertos之资源管理学习
OS下在对硬件外设资源操作.多任务的共享变量.任务和中断的共享变量操作时需要考虑资源的完整性和安全性. FREERTOS提供了临界区.调度器上锁.互斥量.优先级自动继承.创建守护任务的方法来改变最小优 ...
- drupal中文安装指导
(注:drupal6中文包放在profiles/default/translations下,drupal7放在profiles/standard/translations下) Drupal 6 中文安 ...
- BeanUtils 工具类
一.BeanUtils 概述 BeanUtils 是阿帕奇提供的一套专门用于将一些数据封装到java对象中的工具类; 名词:javaBean:特定格式的java类称为java ...
- WebService学习之旅(一)使用JAX-WS发布WebService
JAX-WS全称Java™ API for XML Web Services,是随着JDK1.6及其后续版本发布的方便Java程序员开发WebService应用的一组API,通常简称为JWS,目前版本 ...
- css命名规范—CSS样式命名整理
CSS样式命名整理 页面结构 容器: container/wrap整体宽度:wrapper页头:header内容:content页面主体:main页尾:footer导航:nav侧栏:sidebar栏目 ...