0

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

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

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

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

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

附件是带有倒置调用树的分析器的屏幕截图,因此您可以看到每个项目被调用的内容。

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

步进器的屏幕截图,显示通过握持步进器调用的部分

4

2 回答 2

1

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

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

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

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

在您的情况下,会发生什么是步进器获取触摸,处理它们,并且不将它们转发给连接到它的任何手势识别器。

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

根据苹果文档

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

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

...

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

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

于 2013-12-31T11:00:29.203 回答
0

再次仔细查看 Apple 的文档后,我找到了解决方案。我将视图控制器作为委托添加到长按手势识别器

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,这是问题中提到的子视图。

于 2013-12-31T19:04:07.050 回答