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

时间:2016-03-21 09:36:56

标签: ios swift uiview uibutton ios9

我已经在这几天里一直在努力解决这个问题,并且无法确定问题的原因,正如标题所说,子视图中的UIButton没有解雇IBAction出口当"点击"。

让我详细说明一下,我正在研究一种类似火种的"应用,我使用this third party library。我正在实现自定义视图,其中包含按钮和其他控制器。这些"卡片中的按钮"没有解雇他们的IBAction网点。

据我所知,图书馆执行以下操作:

Stacks 3" DraggableViews"每个可拖动视图都有两个子视图,一个是内容视图,我的自定义视图存在,另一个是叠加视图,顶部有一个图像视图。可拖动视图使用两个手势识别器来完成其工作,第一个是调用委托方法来处理卡中的点击事件(在他们的示例中用于显示浏览器视图)的点击手势。第二个手势是用于实现卡的滑动功能的平移手势。

我完成了我的作业并尝试了一些不同的解决方案,但我无法解决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
       }
    }
    
  • 以编程方式在按钮上实现了点按手势。在viewDidLoad上,我将动作添加到点按手势,但这也不会触发插座。

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

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

我不知道它是否相关,但是我的自定义视图存在于xib文件中,当我将视图传递给库时,我通过实例化视图控制器并传递遍历其视图来执行此操作,如下所示:

if let vc = spiViewConntroller {
        return vc.view
    }

非常感谢任何帮助或建议!

干杯!

修改 继续搜索真相,我已经从库中完全删除了叠加视图,在UI调试器上检查我的自定义视图,我可以看到叠加视图及其ImageView不再存在。该按钮仍然不会触发其插座,因此我可以认为叠加视图不会导致此问题。

我分叉了Koloda图书馆并创建了一个demo example的分支,分支名称为#34; StackOverflowDemo"。我已经添加了一个带有一个按钮的自定义视图,我在其视图控制器中创建了两个出口,我在视图上更改了按钮的标题(可以正常工作)。我还禁用了按钮上的两个手势来复制我目前在我的应用中获得的内容。 如果您确实将其克隆下来,则需要关闭第一张卡片,因为索引0处的卡片不会禁用手势。

我会继续挖掘,希望有人可以找出我做错的事情!

干杯。

3 个答案:

答案 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];
}

答案 1 :(得分:0)

我可以建议一种可以帮助您检测问题的方法。在模拟器运行时使用xcode中的调试器视图。它将以三维模式向您显示视图的层次结构,它可以帮助您找出问题。 如何使用debuggin视图: https://developer.apple.com/library/ios/documentation/ToolsLanguages/Conceptual/Xcode_Overview/ExaminingtheViewHierarchy.html

答案 2 :(得分:0)

好的,我找到了答案。挖了一些后,我能够解决这个问题。然而,我的解决方案感觉很脏,我不确定它是否打破了MVC模式。

我认为我的问题是我的xib文件的自定义View Controller以某种方式丢失或无法响应这些事件。创建要显示为可拖动卡片内容的视图时,我正在创建视图控制器的实例并返回其视图。对我来说奇怪的是视图控制器的ViewDidLoad方法在加载视图时正在完成它的工作(即更改出口的值)。

<强>解决方案: 我从lib中删除了文件所有者,创建了一个继承自UIView的自定义类,例如 MyCustomUIView ,并将视图控制器逻辑,其出口和操作移动到该类。然后在xib文件上,我将内容视图链接到 MyCustomUIView 。然而,这个解决方案感觉很脏,因为我希望视图的视图控制器能够处理所有逻辑。可能需要对笔尖和可重用的视图进行更多阅读。