使用UILongPressGestureRecognizer查看UIScrollview的子视图

在过去的四个小时里,我尝试了很多Stack Overlow解决方案,但没有一个能帮我解决问题。

这里是,

  • 我有一个UIScrollView
  • 在ScrollView中有一个自定义UILabel和8个自定义UIImageViews
  • 我想检测一下长按
  • 像这样的东西有效

    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDidFire:)];
    longPress.minimumPressDuration = 0.5; [scroll addGestureRecognizer:longPress]; //scroll defined elsewhere

但是,如果我将滚动替换为滚动的任何子视图,则长按事件永远不会触发。

  1. 如何检测长按滚动视图的子视图?
  2. 然而,这是一个非常混乱的黑客,因为我可以检测到滚动视图的长按,有什么方法我可以检测到按下的位置,以便我可以看到正在按下哪个特定的子视图。

另外, (insert subview here).userInteractionEnabled = YES ,我为滚动视图的所有子视图设置了此属性,因此这应该不是问题。

我也尝试过使用touchesBegan和touchesEnded方法,如Stack Overflow中其他地方所建议的那样。

此外,对于图像视图,我使用for循环为每个自定义图像视图设置新的UILongPressGestureRecognizer,因为我知道每个手势识别器规则的1个视图

来自第一次iOS开发人员,

格雷厄姆

PS我真的更喜欢我能找到1的解决方案,而不是凌乱的2。


更多代码要求:

在Init视图控制器中

  UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDidFire:)]; longPress.minimumPressDuration = 0.5; [self.titleLabel addGestureRecognizer:longPress]; //titleLabel property initialized elsewhere [mainView addSubview:self.titleLabel]; 

在“加载图像”方法中

 for (NSData * dataImg in results) { //Does some work turning data into an image, into an image view called img img.delegate = self; img.userInteractionEnabled = YES; UILongPressGestureRecognizer *aLongPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressDidFire:)]; aLongPress.minimumPressDuration = 0.5; [img addGestureRecognizer:aLongPress]; [imgContainer addSubview:img]; } 

更多Code + Notes

self.view(UIView)

– >滚动(UIScrollView)

– > – > mainView(UIView)

– > – > – > titleLabel(UILabel)

– > – > – > imgContainer(UIView)

– > – > – > – > images(UIImageViews)

 [self.view addSubview:scroll]; [scroll addSubview:mainView]; [mainView addSubview:self.titleLabel]; [mainView addSubview:imgContainer]; [imgContainer addSubview:img]; //done 8x via for loop 

感谢@ RegularExpression的回答,我现在知道mainView正在被按下,但不是它的子视图,所以我需要找到一种方法来显示它上面的mainView的子视图。 🙂

另一个更新,titleLabel工作。 ImageViews仍然无法正常工作。 🙁

我知道这有点晚了,已经选择了一个答案,但是如果你有iOS7,其他人想要一个很好的简单解决方案。

在您的UILongPressGestureRecognizer委托内部实现gestureRecognizer:shouldRequireFailureOfGestureRecognizer:otherGestureRecognizer选择器

检查otherGestureRecognizer是否为UIPanGestureRecognizer并返回YES,否则返回NO

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { return YES; } return NO; } 

滚动视图实际上会产生一个UIScrollViewPanGestureRecognizer,它是私有API的一部分,但它是UIPanGestureRecognizer的子类,所以上面的工作正常。

要支持iOS6或更低版本,您需要循环遍历UIScrollView的gestureRecognizers,检测哪一个是UIPanGestureRecognizer,并在UILongPressGestureRecogizer上执行requireGestureRecognizerToFail选择器。

你的代码似乎很好,它应该工作我认为。我使用下面的代码,它的工作正常。

 UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; longPress.delegate = (id)self; longPress.minimumPressDuration=0.05; imageView.userInteractionEnabled = YES; [imageView addGestureRecognizer:longPress]; 

和它的方法,

 - (IBAction)handleLongPress:(UILongPressGestureRecognizer *)sender { NSLog(@"detected"); if (sender.state == UIGestureRecognizerStateEnded){ UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"YES" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } } 

正如你所说,我把imageView作为scrollview的子视图

由于您的UIScrollView是常见的父级,因此可能是您的手势识别器需要的位置。 您可以通过查看操作中提供的点的位置来确定正在按下哪个子视图。 因此,各个子视图不需要手势识别器。

所以,你会做这样的事情:

 - (void)longPressDidFire:(UILongPressGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateEnded) CGPoint point = [sender locationInView:scroll]; UIView *tappedView = [scroll hitTest:point withEvent:nil]; 

那么,你有一个长期的观点。

其他可能导致操作无法触发的事情将是委托问题,或者如果滚动包含在另一个拦截触摸的视图中。

HTH

代替

  [scroll addGestureRecognizer:longPress]; 

在您声明它们之后以及将它们添加到scrollview之前,在子视图上添加手势

  [subview addGestureRecognizer:longPress]; 

哇哇它有效!

问题是:

imgContainer是一个带有空框架UIView,其中有几个UIImageViews作为子视图

的印象是,当我向imgContainer添加子视图时,imgContainer会扩展

事实并非如此

我必须将imgContainer的框架设置为与滚动视图相同的内容框架 ,然后一切都变得正常。

我希望这个答案可以帮助像我这样的未来iOS第一次定时器。