IOS 9 - 子视图上的 UIButton 不会触发 IBAction 插座

Dan*_*eño 5 uibutton uiview ios swift ios9

我已经为此苦苦挣扎了几天,但无法查明问题的原因,正如标题所说,子视图上的 UIButton 在“单击”时不会触发 IBAction 插座。

让我详细说明一下,我正在开发一个“类似火种”的应用程序,我正在使用这个第三方库。我正在实现其中包含按钮和其他控制器的自定义视图。这些“卡片”中的按钮不会触发它们的 IBAction 插座。

据我所知,该库执行以下操作:

将 3 个“DraggableViews”堆叠在一起,每个可拖动视图有 2 个子视图,一个是内容视图,我的自定义视图所在的位置,另一个是覆盖视图,顶部有一个图像视图。可拖动视图使用两个手势识别器来做它的事情,第一个是一个点击手势,它调用一个委托方法来处理卡片中的点击事件(在他们的例子中,它用于显示浏览器视图)。第二个手势是平移手势,用于实现卡片的滑动功能。

我已经完成了作业并尝试了几种不同的解决方案,但我无法触发 IBAction。我尝试了以下方法:

  • 当在按钮上触发触摸事件时,使用 DraggableViews 的父视图禁用手势识别器。- 这有效(手势被禁用)但不会触发 IBAction。在平移手势的情况下,我不再能够在触摸按钮时“滑动”卡片,并且点击事件不会在上述委托方法中击中断点。在 UI 中,我的按钮在动画时对触摸做出反应,但它在视图控制器中的出口未能命中断点。我已经禁用了这个:

    //- Called when each DraggableView is visible (not called for view at index 0, but works alright for debugging in the mean time)
    func koloda(koloda: KolodaView, didShowCardAtIndex index: UInt) {
     let subviews = koloda.subviews
     for subview in subviews {
        if let recognizers = subview.gestureRecognizers {
            for gesture in recognizers {
                if gesture is UIPanGestureRecognizer || gesture is UITapGestureRecognizer{
                    //- Also tried setting this to false but nothing.
                    gesture.cancelsTouchesInView = false 
                    gesture.delegate = self
                }
            }
        }
    }
    
    //- On the gestureRecognizerDelegate
    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
       if touch.view is UIButton {
         return false
       } else {
         return true
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 以编程方式在按钮上实现点击手势,在 viewDidLoad 上,我将操作添加到点击手势,但这也不会触发插座。

  • 以编程方式将 ImageView 的 userInteractionEnabled 属性设置为 True 希望这将允许触摸事件通过响应者链(尽管我在另一篇文章中读到这会产生相反的效果?)。

我还检查了故事板,我的自定义视图中的所有相关视图和控制器都启用了 userInteractionEnabled 选项。

我不知道它是否相关,但我的自定义视图存在于一个 xib 文件中,当我将视图传递给库时,我通过实例化视图控制器并传递它的视图来完成它,如下所示:

if let vc = spiViewConntroller {
        return vc.view
    }
Run Code Online (Sandbox Code Playgroud)

任何帮助或建议将不胜感激!

干杯!

编辑: 继续寻找真相,我已经从库中完全删除了覆盖视图,在 UI 调试器上检查了我的自定义视图,我可以看到覆盖视图及其 ImageView 不再存在。该按钮仍然不会触发其出口,因此我可以假设叠加视图不会导致此问题。

我已经分叉了 Koloda 库并创建了一个带有演示示例的分支,分支名称是“StackOverflowDemo”。我添加了一个带有一个按钮的自定义视图,我在其视图控制器中创建了两个出口,我在视图加载时更改了按钮的标题(有效)。我还禁用了按钮上的两个手势以复制我当前在我的应用程序中获得的内容。如果您确实将其克隆下来,则需要将第一张卡刷掉,因为索引 0 处的卡不会禁用手势。

我会继续挖掘,希望有人能指出我做错了什么!

干杯。

小智 4

丹尼尔. 您的问题是您没有将视图控制器添加为与 Koloda 一起操作的视图控制器的子视图控制器。结果中显示了您的 vc.view,因为 Koloda 保留了它,但没有人保留您的视图控制器,因此您将丢失重要的生命周期方法,并且它会被释放。

您尝试使用的方法称为容器视图控制器。Apple 在此提供了有关其实现的建议:https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html

这里简单实现:

- (void) displayContentController: (UIViewController*) content {
   [self addChildViewController:content];
   content.view.frame = [self frameForContentController];
   [self.view addSubview:self.currentClientView];
   [content didMoveToParentViewController:self];
}
Run Code Online (Sandbox Code Playgroud)