三指捏合手势
Posted
技术标签:
【中文标题】三指捏合手势【英文标题】:Three finger pinch gesture 【发布时间】:2012-12-08 13:51:34 【问题描述】:我在尝试实现 3 指捏合时遇到了一些问题。
我一直在单独使用 2 指捏合和 2 指旋转! (不需要或不需要同时手势)问题是很多时候,系统识别出错误的动作,因为它们都非常相似,所以我最终不得不移开手指并再次按下以尝试让系统识别旋转(通常它首先识别夹点)
我搜索了很多以查看delayBegin
是否有帮助,或者我是否可以做一些激活同时手势的操作,但没有一个可以正常工作,所以我的想法是不要使用 2 根手指捏,我可以使用 3 (因为捏比旋转更容易)。
问题是,如您所知,Pinch 仅适用于 2 个手指。所以我决定我可以继承 UIPinchGestureReconizer
并且只允许它在屏幕上有 3 个手指时工作。其余的它可以像标准捏合一样工作,即使忽略无名指(计算比例)但确保无名指仍在屏幕上。
所以我为我的 ThreeFingerPinchRecognizer
尝试了以下实现(即 Sub 类 UIPinchGestureRecognizer
)
@implementation GRThreeFingerPinchRecognizer
-(id)initWithTarget:(id)target action:(SEL)action
self = [super initWithTarget:target action:action];
if(self)
return self;
- (void)reset
[super reset];
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
int numberOfTouches = event.allTouches.count;
if (numberOfTouches == 3)
[super touchesBegan:touches withEvent:event];
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
int numberOfTouches = event.allTouches.count;
if (numberOfTouches == 3)
[super touchesMoved:touches withEvent:event];
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
[super touchesEnded:touches withEvent:event];
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
[super touchesCancelled:touches withEvent:event];
因此,如您所见,我正在尝试获得与两指捏合相同的功能(仅通过调用 [super]
函数,在 touchesBegan
和 touchesMoved
函数中,我正在测试如果屏幕上有 3 个手指(通过查看 event.alltouches.count
)
有了这个,两根手指的旋转效果很好,但是捏的效果不是很好,很难激活它,当它激活时,它不能像两根手指捏一样工作......
我知道我可能做错了,所以任何帮助都会很棒!
非常感谢!
【问题讨论】:
有趣的方法,但 PinchGestureRecognizer (最后你正在调用它)可能期望 2 次触摸而不是 3 次,我可能会在你调用 super 之前尝试删除其中一个触摸......你要去必须弄清楚要删除哪个.. 我相信这是在 PinchGesture 内部处理的,因为我没有在事件通过时更改任何内容,我只是转发它!如果我删除“如果”,捏能正常工作(但用 2 个手指) *注意:3 指功能不适用于启用了缩放设置的用户设备(Apple 功能,您可以用 3 根手指双击屏幕进行放大(在任何应用程序中,很多就像屏幕截图功能在任何应用程序中的工作方式一样))...使用 3 更精细的应用程序功能检测可能与使用主页按钮检测功能一样致命。 (我和其他许多人都启用了此缩放功能) 您为什么不创建自己的 UIGestureRecognizer 子类并实际检查 2 个手指的移动,然后相应地选择手势?随着手指的移动,捏住应该使触摸保持在原始 2 点的段内,或接近它。另一方面,旋转应该将它们显着移开。 你能不能不用两根手指捏住,用一个手指移动来旋转? 【参考方案1】:查看此片段可以帮助您识别捏合状态:
if (pinch.numberOfTouches > 1)
CGPoint firstPoint = [pinch locationOfTouch:0 inView:self];
CGPoint secPoint = [pinch locationOfTouch:1 inView:self];
currentUpperY = MIN(firstPoint.y, secPoint.y);
if (previousY == 0) previousY = currentUpperY;
Float32 y = (self.contentOffset.y + previousY - currentUpperY);
[self setContentOffset:CGPointMake(0, y < 0 ? 0 : y) animated:NO];
if (pinch.state == UIGestureRecognizerStateBegan)
pinchStarted = YES;
firstY = MIN(firstPoint.y, secPoint.y);
secondY = MAX(firstPoint.y, secPoint.y);
NSArray *pinchedIndexs = [self indexPathsForRowsInRect:CGRectMake(0.0, firstY, CGRectGetWidth(self.bounds), secondY)];
if (pinchedIndexs.count) itemToOpenOrClose = [[currentItems subarrayWithRange:NSMakeRange(((NSIndexPath *)[pinchedIndexs objectAtIndex:0]).row, pinchedIndexs.count - 1)] copy];
if ((pinch.state == UIGestureRecognizerStateChanged && pinchStarted && itemToOpenOrClose.count)
|| pinch.state == UIGestureRecognizerStateEnded)
if (pinch.scale > 1) // Pinch OUT
for (Item *item in itemToOpenOrClose)
[self openItem:item inIndexPath:[NSIndexPath indexPathForRow:[currentItems indexOfObject:item] inSection:0]];
else if (pinch.scale < 1) // Pinch IN
for (Item *item in itemToOpenOrClose)
[self closeItem:item inIndexPath:[NSIndexPath indexPathForRow:[currentItems indexOfObject:item] inSection:0]];
if (pinch.state == UIGestureRecognizerStateEnded)
pinchStarted = NO;
itemToOpenOrClose = nil;
previousY = 0;
【讨论】:
以上是关于三指捏合手势的主要内容,如果未能解决你的问题,请参考以下文章