如何让步进和长按共存?

时间:2013-12-30 20:59:40

标签: ios long-press uistepper

我尝试使用longpress手势和配置为持续更新的步进器设置视图。使用长按,不会发生步进器的连续特征。现在,我已经禁用了长按。我想我不需要它。但是为了将来参考,我将如何允许两者共存?

为了清楚起见,这是我尝试使用屏幕时的设置方式。

  • 应用程序设置了一个简单的视图控制器。
  • 在这个视图中添加了一个子视图(可能是一个控制器,但我只是把它作为UIView)。
  • 此子视图中添加了多个标签和步进器。
  • 步进器被连接起来作为出口和行动。
  • 长按识别器已添加到IB的主视图中。
  • 为了完整起见,还在IB的主视图中添加了一个轻击手势。

按预期点击主视图功能。步进器上的点击按预期运行。主视图上的Longpress按预期运行。步进器上的Longpress没有。

我修改了longpress调用的代码以检查子视图的框架,如果触摸位置在该矩形内,则不动作,但这没有任何区别。在那种情况下,我没有尝试让长按失败,但我想我接下来会尝试。编辑:好的,也许不是。似乎没有一个API。但是,有this kludge,我不会尝试。

附件是来自具有倒置调用树的探查器的屏幕截图,因此您可以看到每个项目被调用的内容。

darkStepped:是步进器调用的IBAction。如果步进器由手势识别器触发,我不期望在调用树中看到手势识别器吗?

Screen shot of stepper showing section called by holding stepper

2 个答案:

答案 0 :(得分:1)

  

如果步进器是由手势识别器触发的,我是不是希望在调用树中看到手势识别器?

堆栈跟踪显示步进器的_updateCount方法是通过计时器调度的。

这可能与步进器具有" autoIncrement"模式,只要按住它,它就会以给定(变化)的速率更新。因此,步调器不是简单地调用_updateCount,而是设置一个计时器来处理这种行为。

无论出于何种原因使用计时器,计时器都会解释您在堆栈跟踪中没有看到手势识别器的原因。

在你的情况下,发生的事情是步进器获得触摸,处理它们,并且不将它们转发到任何附加到它上的手势识别器。

这可以解释如下,尽管此代码段未明确提及与UIStepper控件相关的长按识别器:

根据Apple Docs

  

与其他用户界面控件交互   在iOS 6.0及更高版本中,默认控制操作可防止重叠手势识别器行为。例如,按钮的默认操作是单击。如果您将单击手势识别器附加到按钮的父视图,并且用户点击该按钮,则该按钮的操作方法将接收触摸事件而不是手势识别器。这仅适用于与控件的默认操作重叠的手势识别,其中包括:

     

单指单击UIButton,UISwitch,UIStepper,UISegmentedControl和UIPageControl。

     

...

     

如果您有其中一个控件的自定义子类并且想要更改默认操作,请将手势识别器直接附加到控件而不是父视图。然后,手势识别器首先接收触摸事件。与往常一样,请务必阅读iOS人机界面指南,以确保您的应用程序提供直观的用户体验,尤其是在覆盖标准控件的默认行为时。

因此,似乎您可以将手势识别器直接附加到控件上(可能需要子类UIStepper才能使其工作,我不确定如何解释最后一段)。希望这不会禁用步进器的基本工作方式(但也许会禁用)。

答案 1 :(得分:0)

在仔细审阅Apple的文档之后,我找到了解决方案。我添加了视图控制器作为longpress手势识别器的委托

self.longPress.delegate = self;

(当然,将<UIGestureRecognizerDelegate>添加到接口,然后将此方法添加到视图控制器:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
   // Determine if the touch is inside the custom subview
   if (gestureRecognizer == self.longPress) {
      CGPoint touchLocation = [touch locationInView:self.view];
      if (CGRectContainsPoint(self.antControl.frame, touchLocation)) {
         return NO;
      }
   }
   return YES;
}

这样,当在self.antControl的框架内发生长按时,手势识别器甚至不会被调用,这是问题中提到的子视图。