UIPanGestureRecognizer 触摸时立即执行某些操作
Posted
技术标签:
【中文标题】UIPanGestureRecognizer 触摸时立即执行某些操作【英文标题】:UIPanGestureRecognizer do something immediately when touched 【发布时间】:2013-07-12 18:12:57 【问题描述】:我是 ios 新手,所以如果我遗漏了一些明显的东西,我提前道歉。
我正在创建一个拼图,我希望各个拼图在触摸时增大,在放开时减小。
目前我有:
-(IBAction)handlePan:(UIPanGestureRecognizer *)recognizer
if(recognizer.state == UIGestureRecognizerStateBegan)
else if(recognizer.state == UIGestureRecognizerStateEnded)
拼图在平底锅开始时(也是状态开始时)会增大,在平底锅结束时会变小(如预期的那样)。一旦用户触摸了一块并且在拼图块移动之前,我希望尺寸增加。选择图块时,在 Words With Friends 中可以看到这一点。
我试过了
-(IBAction)handleTap:(UITapGestureRecognizer *)recognizer
if(recognizer.state == UIGestureRecognizerStateBegan)
else if(recognizer.state == UIGestureRecognizerStateEnded)
这只会在手指抬起后增加拼图。
我的问题:
有没有办法在手指触摸拼图块后增加拼图块的大小,然后继续平移手势。
提前谢谢你。
【问题讨论】:
是的,缺少“中间”状态。您必须跟踪它以查看它们是否已经开始移动 (translationInView
)。
【参考方案1】:
我也需要这样做,而 Jake 的建议对我来说非常有效。如果它对将来遇到此问题的任何人有所帮助,这是我的UIPanGestureRecognizer
的子类实现(标题保持不变):
#import "ImmediatePanGestureRecognizer.h"
#import <UIKit/UIGestureRecognizerSubclass.h>
@implementation ImmediatePanGestureRecognizer
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
[super touchesBegan:touches withEvent:event];
self.state = UIGestureRecognizerStateBegan;
@end
这就是你所需要的——只要你将手指放在视图上就会触发,只要你在任何方向上移动手指一点就会更新,并提供常规 UIPanGestureRecognizer
的功能(就像translationInView
和velocityInView
) 一样,在一个普通的被解雇之前,所有这些都不会破坏任何现有的功能。
2020 年 Swift 5 的复制粘贴
import UIKit // (nothing extra needed to import with Swift5)
fileprivate class ImmediatePanG: UIPanGestureRecognizer
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent)
super.touchesBegan(touches, with: event)
self.state = .began
【讨论】:
你真是个天才,我从没想过会这样做。手势识别器将使用相同的状态值调用其选择器两次... 如果我们在本身有 touchesBegan 方法的 UIview 上实现 ImmediatePanGestureRecognizer 怎么办?我们如何确定优先级? @GeorgeWS,如果您看到此消息,我只是在您的“著名答案”中修复了当前的 Swift!显然,请随意回滚、编辑等,干杯!【参考方案2】:Swift 3/4/5 解决方案
class InstantPanGestureRecognizer: UIPanGestureRecognizer
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent)
if self.state == .began return
super.touchesBegan(touches, with: event)
self.state = .began
【讨论】:
【参考方案3】:我已经实现了 George WS 的回答。通过一些测试,我意识到在初始触摸之后但在初始触摸结束之前发生的其他触摸事件没有得到正确处理。这是我更新的实现。这有点幼稚,但可以防止 UIGestureRecognizerStateBegan 多次发生导致的奇怪行为。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
if (self.state >= UIGestureRecognizerStateBegan)
return;
[super touchesBegan:touches withEvent:event];
self.state = UIGestureRecognizerStateBegan;
【讨论】:
【参考方案4】:根据the documentationUIPanGestureRecognizer
仅在“允许的最小手指数(minimumNumberOfTouches)移动到足以被视为平移”时进入 UIGestureRecognizerStateBegan。如果您希望在触摸时立即发生某些事情,您可以尝试继承 UIPanGestureRecognizer 并覆盖 touchesBegan:withEvent:
。
【讨论】:
【参考方案5】:感谢 George WS 和 Derrick Hathaway
斯威夫特 2.2
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent)
if (self.state == UIGestureRecognizerState.Began)
return
super.touchesBegan(touches, withEvent: event)
self.state = UIGestureRecognizerState.Began;
而且您必须添加到您的 Bridging-Header:
#import <UIKit/UIGestureRecognizerSubclass.h>
【讨论】:
【参考方案6】:我在一个属于 UIScrollView 的视图中绘制。我使用 UIPanGestureRecognizer 在视图中绘制。此 UIPanGestureRecognizer 将 minimumNumberOfTouches 和 maximumNumberOfTouches 设置为 1。
我使用滚动视图中的 UIPinchGestureRecognizer 和 UIPanGestureRecognizer 进行平移和缩放。 scrollView 的 UIPanGestureRecognizer 的 minimumNumberOfTouches 和 maximumNumberOfTouches 设置为 2。
我使用了 George WS 的解决方案,我注意到绘图开始很快,但很难识别用于缩放的捏合手势和用于平移的两指平移手势。我稍微改变了解决方案,并使用 touchesMoved 来识别绘图的开始。可以更好地识别缩放和平移。
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent)
super.touchesMoved(touches, with: event)
state = UIGestureRecognizer.State.began
【讨论】:
我也是这样。感谢您的想法!【参考方案7】:我正在尝试做类似的事情,我一直在研究的解决方案是使用视图的 touchesBegan:withEvent: 来执行我想要在用户触摸屏幕的那一刻发生的操作。然后,一旦触摸变成手势,手势处理程序就会接管。
【讨论】:
以上是关于UIPanGestureRecognizer 触摸时立即执行某些操作的主要内容,如果未能解决你的问题,请参考以下文章
UIPanGestureRecognizer:在滑动结束时检测触摸位置
Swift:你如何使用 UIPanGestureRecognizer 获得每次触摸的速度?
使用 UIPanGestureRecognizer 拖动 + 旋转触摸下车
无需触摸手动启动 UIPanGestureRecognizer