【问题标题】:Proper UIGestureRecognizer and Delegate design正确的 UIGestureRecognizer 和 Delegate 设计
【发布时间】:2015-04-25 13:01:24
【问题描述】:

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

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

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

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

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

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

我能想到的唯一方法是将所有手势处理程序连接到 ViewController 并让它做所有事情,但对我来说这破坏了封装,因为现在它必须知道地图手势需要同时运行,抽屉应该只接触它的把手,地图应该只在它打开时接触。

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

【问题讨论】:

    标签: ios uiview uigesturerecognizer gesture uicontrol


    【解决方案1】:

    我会做这样的事情来使抽屉的子视图在平移时禁用。基本上循环遍历抽屉的子视图并禁用它们的交互。

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

    当您想要在子视图上重新启用用户交互时,再次类似的东西。

    【讨论】:

    • 我不能说这个解决方案行不通,但它超出了可用的手势工具。那是因为 Superviews 没有适当的方法来控制他们的 Subviews 手势行为(除了作为代表之外)?
    【解决方案2】:

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

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

    或者您的意思是要阻止用户在打开抽屉的中途使用另一个手指(即另一个手势)开始滚动(半可见)地图?如果是这样,您应该将抽屉的contentView(或等效项)上的userInteractionEnabled 设置为NOUIGestureRecognizerStateBegan/ChangedYES 再次UIGestureRecognizerStateEnded/Cancelled

    【讨论】:

    • 实际用例是抽屉正在移动(没有触摸),因为它是从以前的手指拖动/轻弹给出的速度......然后,用户转到停止抽屉移动并触摸激活地图拖动的地图(孩子)......所以他们没有阻止抽屉关闭,而是平移地图并且抽屉继续关闭。听起来您的第 3 段更适用,并且您提出的建议与 lramirez135 在他的回答中所做的非常相似。这似乎是有道理的,所以我认为我需要给予他信任。但感谢您的澄清。
    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    相关资源
    最近更新 更多