【问题标题】:Determining Location of A Long Press Gesture Recognizer确定长按手势识别器的位置
【发布时间】:2012-04-05 01:57:43
【问题描述】:

目前,我在四个不同的 TableView 上有长按手势识别器(每个情节提要场景中有两个,因此两个情节提要场景)。我在 ViewDidLoad 方法中使用以下代码创建这些 LPGR...

//Add Long Press Gesture Reconizer
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] 
                                      initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 1; //seconds
lpgr.delegate = self;
[self.GolferOne addGestureRecognizer:lpgr];
[self.GolferTwo addGestureRecognizer:lpgr];
[self.GolferThree addGestureRecognizer:lpgr];
[self.GolferFour addGestureRecognizer:lpgr];
//Done Adding Long Press Gesture Reconizer

接下来我有另一种方法,我想在按下 LPG 的地方进行 NSLog...

CGPoint p = [gestureRecognizer locationInView:self.GolferOne];

   NSIndexPath *indexPath = [self.GolferOne indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row [Golfer One]");
    else
        NSLog(@"long press on table view at row %d [Golfer One]", indexPath.row);

    //Golfer Two

    p = [gestureRecognizer locationInView:self.GolferTwo];

    indexPath = [self.GolferTwo indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row [Golfer Two]");
    else
        NSLog(@"long press on table view at row %d [Golfer Two]", indexPath.row);

    //Golfer Three

    p = [gestureRecognizer locationInView:self.GolferThree];

    indexPath = [self.GolferThree indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row [Golfer Three]");
    else
        NSLog(@"long press on table view at row %d [Golfer Three]", indexPath.row);

    //Golfer Four

    p = [gestureRecognizer locationInView:self.GolferFour];

    indexPath = [self.GolferFour indexPathForRowAtPoint:p];
    if (indexPath == nil)
        NSLog(@"long press on table view but not on a row [Golfer Four]");
    else
        NSLog(@"long press on table view at row %d [Golfer Four]", indexPath.row);

我知道为什么它不起作用,但我找不到让它起作用的解决方案。它不仅仅是返回一个 NSLog,而是返回四次(每个高尔夫球手一次,因为其中三个有 indexPath=nil)

任何帮助将不胜感激。还有为什么它对 NSLog 有这么大的滞后?

【问题讨论】:

    标签: iphone objective-c ios cocoa-touch cocoa


    【解决方案1】:

    从识别器的 locationInView: 属性确定手势在视图中的位置:

    // Get the location of the gesture
    CGPoint location = [recognizer locationInView:self.view];
    

    【讨论】:

    • 这就是我想要的。比 KVC 好得多 ;-)
    【解决方案2】:

    您可以使用,获取识别器的接触点,

     -(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
    {
     NSLog(@"%@",NSStringFromCGPoint([[gestureRecognizer valueForKey:@"_startPointScreen"] CGPointValue]));
    
    }
    

    您将获得与添加了识别器的视图坐标系统相关的点。

    您的识别器仅为最后一位 Golfer 注册。你应该这样做,

    UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] 
                                          initWithTarget:self action:@selector(handleLongPress:)];
    lpgr.minimumPressDuration = 1; //seconds
    [self.GolferOne addGestureRecognizer:lpgr];
    [lgpr release];
    lpgr = [[UILongPressGestureRecognizer alloc] 
                                          initWithTarget:self action:@selector(handleLongPress:)];
    lpgr.minimumPressDuration = 1; //seconds
    
    [self.GolferTwo addGestureRecognizer:lpgr];
    [lgpr release];
    

    【讨论】:

    • 但是,在手册中,“valueForKey”在哪里解释了 UIGestureRecognizer??
    • valueForKey 是 KVC。 KVC 可以应用于任何符合 KVC 的对象。
    • 我知道这个旧的,但对于将来遇到这个的任何人。如果要确定长按哪一行,则需要使用 CGPoint p = [gestureRecognizer locationInView:myTableView];键 _startPointScreen 的值是偏移的,使用 NSIndexPath *indexPath = [myTableView indexPathForRowAtPoint:p]; 时将返回错误的行;
    【解决方案3】:

    长按识别器应用于整个视图。要使 NSLog 出现“滞后”,您可以使用 NSTimer。获得想要的结果的一种方法是 alpha 为零的按钮。当他们释放(无论是 1 秒还是 120 秒)时,它会记录触摸。

    【讨论】:

      【解决方案4】:
      1. 正如 TheDeveloper 所说,长按手势适用于整个视图。

      2. 顺便说一句,如果您要为多个视图设置手势,我相信您需要为每个视图设置一个单独的手势识别器。这里不相关,但我看到很多人想知道为什么他们试图分配给多个视图的手势只对一个视图有效。

      3. 使用长按手势,我建议您检查 sender.state == UIGestureRecognizerStateEnded 或 Started 或您要查找的任何内容。您将为一次用户交互触发多个事件。

      4. 如果您在视图上有手势并且想要查看,例如,如果用户在特定子视图上松开手指,您可以获得用于释放的 CGPoint(通过 locationInView正如 Vignesh 指出的那样),您还可以获取特定子视图框架的 CGRect,然后通过 CGRectContainsPoint() 检查 CGPoint 是否在 CGRect 内。

      【讨论】:

      • 另请注意,您将获得相对于其坐标系的积分。所以CGRectContaintsPoint只有在坐标系转换后才能有效使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2015-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多