您的位置:首页 > 产品设计 > UI/UE

UIPanGestureRecognizer使用小结

2013-12-15 14:10 253 查看
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));

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: