【问题标题】:IOS 9 - UIButton on subview does not fire IBAction outletIOS 9 - 子视图上的 UIButton 不会触发 IBAction 插座
【发布时间】:2016-07-07 17:55:07
【问题描述】:

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

让我详细说明一下,我正在开发一个“类似火种”的应用程序,我正在使用 this third party library。我正在实现自定义视图,其中包含按钮和其他控制器。这些“卡片”中的按钮不会触发它们的 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
       }
    }
    
  • 以编程方式在按钮上实现了点击手势,在 viewDidLoad 上,我将操作添加到点击手势,但这也不会触发插座。

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

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

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

if let vc = spiViewConntroller {
        return vc.view
    }

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

干杯!

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

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

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

干杯。

【问题讨论】:

    标签: ios swift uiview uibutton ios9


    【解决方案1】:

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

    您尝试使用的方法称为容器视图控制器。苹果在这里有关于其实施的建议: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];
    }
    

    【讨论】:

    • 你好尤金,谢谢你的回复,这很有意义。我发现了一个建议此解决方案的堆栈溢出问题,但查看代码我不完全确定如何在不修改 koloda 库的情况下将我的视图控制器添加到可拖动视图。我正在使用一个包含 koloda 视图实例的 ViewController,解决方案是将我的自定义视图控制器添加为实际 koloda 视图的子级吗?我将阅读更多关于 Container View 控制器的内容。再次感谢您的回复。
    【解决方案2】:

    好的,我找到了答案。在挖掘了更多之后,我能够解决这个问题。但是我的解决方案感觉很脏,我不确定它是否破坏了 MVC 模式。

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 您好 Ray_Soham,感谢您的建议。我已经使用视图调试器来验证是否没有视图,似乎位于按钮顶部的唯一视图是我的问题中提到的覆盖视图,该视图包含一个 UIImageView 覆盖其所有父级.找到这个后,我尝试将其 userInteractionEnabled 属性设置为 true,但这并没有解决问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多