Iphone 如何捕获最初在UIPangestureRecognitor中点击的点?
我有一个应用程序,可以让用户跟踪屏幕上的线条。我是通过在UIPangestureRecognitor中记录点来实现的:Iphone 如何捕获最初在UIPangestureRecognitor中点击的点?,iphone,objective-c,ios,uigesturerecognizer,pan,Iphone,Objective C,Ios,Uigesturerecognizer,Pan,我有一个应用程序,可以让用户跟踪屏幕上的线条。我是通过在UIPangestureRecognitor中记录点来实现的: -(void)handlePanFrom:(UIPanGestureRecognizer *)recognizer { CGPoint pixelPos = [recognizer locationInView:rootViewController.glView]; NSLog(@"recorded point %f,%f",pixelPos.x,pixelPo
-(void)handlePanFrom:(UIPanGestureRecognizer *)recognizer
{
CGPoint pixelPos = [recognizer locationInView:rootViewController.glView];
NSLog(@"recorded point %f,%f",pixelPos.x,pixelPos.y);
}
那很好。然而,我对用户在开始平移之前点击的第一点非常感兴趣。但是上面的代码只给出了在手势被识别为平移(而不是轻敲)后发生的点
从文档中可以看出,似乎没有简单的方法来确定UIPangestureRecognitor API中的初始点击位置。尽管在UIPanGestureRecognizer.h中,我发现了以下声明:
CGPoint _firstScreenLocation;
…看起来是私人的,所以运气不好。我正在考虑完全脱离UIGestureRecognizer系统,只是为了捕获最初点击的点,然后在我知道用户确实已经开始UIPanGesture后再参考它。不过,在走这条路之前,我想在这里问一下。您可以使用UIGestureRecognitzerStateStarted方法。以下是指向UIgestureRecognitor类的Apple文档的链接
您应该能够使用来计算起始位置,除非在两者之间重置它。获取触摸的平移和当前位置,并使用它来查找触摸的起点。您可以使用以下方法:
CGPoint point = [gesture locationInView:self.view];
在相同的UIView中放入此方法
//-----------------------------------------------------------------------
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint point = [[[event allTouches] anyObject] locationInView:self];
NSLog(@"point.x ,point.y : %f, %f",point.x ,point.y);
}
请在以下UIgestureRecognitor类参考中查找:
晚会迟到了,但我注意到上面没有任何东西能真正回答这个问题,事实上有一种方法可以做到这一点。您必须将UIPanGestureRecognizer子类化,并包括:
#import <UIKit/UIGestureRecognizerSubclass.h>
#导入
要么在编写类的Objective-C文件中,要么在Swift桥接头中。这将允许您覆盖ToucheSBegind:withEvent方法,如下所示:
class SomeCoolPanGestureRecognizer: UIPanGestureRecognizer {
private var initialTouchLocation: CGPoint!
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event)
initialTouchLocation = touches.first!.locationInView(view)
}
}
类somecoolPangEstureRecognitor:UIPangEstureRecognitor{
private var initialTouchLocation:CGPoint!
覆盖func touchesBegined(触摸:设置,withEvent事件:UIEvent){
super.touchsbegind(touchs,withEvent:event)
initialTouchLocation=touchs.first!.locationInView(视图)
}
}
然后,您的属性initialTouchLocation将包含您要查找的信息。当然,在我的例子中,我假设触摸集合中的第一次触摸是感兴趣的,如果你的最大触摸次数为1,这是有意义的。你可能想用更复杂的方法来寻找兴趣点
编辑:Swift 5
import UIKit.UIGestureRecognizerSubclass
class InitialPanGestureRecognizer: UIPanGestureRecognizer {
private var initialTouchLocation: CGPoint!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
initialTouchLocation = touches.first!.location(in: view)
}
}
导入UIKit.UIgestureRecognitizerSubclass
类InitialPangEstureRecognitor:UIPangEstureRecognitor{
private var initialTouchLocation:CGPoint!
覆盖func touchesStart(touchs:Set,带有事件:UIEvent){
super.touchesbeated(touches,with:event)
initialTouchLocation=touchs.first!.location(在:视图中)
}
}
哇,晚了几年。。我遇到了这个问题,但用一个静态变量解决了它:
- (IBAction)handleGesture:(UIPanGestureRecognizer *)recog {
CGPoint loc = [recognizer locationInView:self.container];
static CGFloat origin = 0.0f;
switch (recognizer.state) {
case UIGestureRecognizerStateBegan:
origin = loc.x;
break;
case UIGestureRecognizerStateChanged:
case UIGestureRecognizerStatePossible:
// origin is still set here to the original touch point!
break;
case UIGestureRecognizerStateEnded:
break;
case UIGestureRecognizerStateFailed:
case UIGestureRecognizerStateCancelled:
break;
}
}
该变量仅在识别器状态为UIgestureRecognitizerStart时设置。由于变量是静态的,因此该值将保留到以后的方法调用
在我的例子中,我只需要x坐标,但如果需要,你可以将其更改为CG点。@John Lawrence做对了 为Swift 3更新:
我还注意到,当我尝试在UIPangestureRecognitor上读取shouldBegin方法中的值时,我只在用户移动一点后(即,当手势开始识别pan时)才看到它的位置。这将是非常有用的,知道这个泛手势实际上是从哪里开始的,这样我就可以决定它是否应该识别 如果不想将UIgestureRecognitor视图作为子类,则有两个选项:
解决方案1:UILongPressGestureRecognitor 优点:简单 不利于:与其他手势处理者友好相处 创建手势时,确保设置为
0
。这将确保您的所有代理方法(例如,应该开始)都能正确地接受第一次触摸
由于UILongPressGestureRecognitor是一个(与离散手势识别器相反),因此可以通过处理属性来处理移动,就像处理UIPangEstureRecognitor(也是一个连续手势识别器)一样。从本质上说,你是
解决方案2:UIPangestureRecognitor 适合:与其他手势识别器配合使用 不利于:保存启动状态需要花费更多的精力 步骤如下:
触摸位置(in:self)
而不是手势识别器。位置(in:self)
,因为前者是准确获取起始位置的唯一方法
现在,您可以在任何需要的地方使用gestureStartPoint
,例如应该开始:
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return isValidStartPoint(gestureStartPoint!)
}
不幸的是,事实并非如此。在最初的解释中,我应该更具体一些:我实际上在case switch语句中使用uigestureRecognitizerStateStateStart来检测平移手势的开始。
func handlePan (_ sender: PanRecognizerWithInitialTouch) {
let pos = sender.location(in: view)
switch (sender.state) {
case UIGestureRecognizerState.began:
print("Pan Start at \(sender.initialTouchLocation)")
case UIGestureRecognizerState.changed:
print(" Move to \(pos)")
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(gestureHandler(_:))
gestureRecognizer.minimumPressDuration = 0
var gestureStartPoint: CGPoint? = nil
// ...
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(gestureHandler(_:))
gestureRecognizer.delegate = self
// ...
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
gestureStartPoint = touch.location(in: self)
return true
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return isValidStartPoint(gestureStartPoint!)
}