正确的UIGestureRecognizer和Delegate设计

时间:2015-02-24 01:27:30

标签: ios uiview uigesturerecognizer gesture uicontrol

这是一个非常假设的问题,只是为了理解正确的设计,但我想说我有两个自定义的UIViews。

其中一个本质上是一个容器,我称之为抽屉。其目的是隐藏和显示内容。它与iOS上的通知中心非常相似,您可以将其拉开以将其拉开并轻弹以将其关闭。它是一个通用容器,可以包含任何其他UIView。它有一个UIPanGestureRecognizer来跟踪拉动它打开/关闭的手指。它也可能有一个UISwipeGestureRecognizer来检测“轻弹”。

另一个视图是具有UIPan / Rotation / Pinch GestureRecognizers的自定义地图窗口小部件。

我认为抽屉视图应该是Pan / Swipe GestureRecognizers的UIGestureRecognizerDelegate,这样它就可以防止触摸被传递,除非用户抓住“手柄”。

我的第一直觉是让地图成为平移/旋转/捏合手势的UIGestureRecognizerDelegate,这样它就可以让它们全部同时运行。

我遇到的问题是,我真的不希望地图接收任何触摸或开始识别手势,直到抽屉完全打开。我希望能够在抽屉本身中自动强制执行此行为,以便它可以立即用于所有子视图。

我能想到的唯一方法就是将所有的手势处理程序连接到ViewController并让它完成所有操作,但对我来说打破封装,因为现在它必须知道地图手势需要同时运行,抽屉应该只触及它的手柄,而地图只应在打开时接触。

有哪些方法可以将逻辑保留在我认为属于的视图中?

2 个答案:

答案 0 :(得分:0)

我会做这样的事情,以便在平移时禁用抽屉的子视图。基本上循环通过抽屉的子视图和对它们的分离互动。

[self.subviews enumerateObjectsUsingBlock:^(UIView *subview, NSUInteger idx, BOOL *stop){
    subview.userInteractionEnabled = NO;
}];

当您想要在子视图上重新启用用户交互时再次出现类似情况。

答案 1 :(得分:0)

这应该是Just Work™。手势识别器附在视图上;当识别出连续手势时,与该手势相关联的所有后续触摸都与该视图相关联。

因此,在您的情况下,当识别出抽屉盘时,与该盘相关联的触摸不应该在地图视图的平移/捏合/旋转手势中引起行为(除非您明确指定它们应该使用适当的委托方法)。

或者你的意思是你想要阻止用户,在打开抽屉的中途,用另一个手指(即另一个手势)开始滚动(半可见)地图?如果是这样,您应该只在userInteractionEnabled / contentView和{{1}将抽屉NO(或等效号)上的UIGestureRecognizerStateBegan设置为Changed }再次在YES / UIGestureRecognizerStateEnded