按钮明显点击但事件未注册

Button visibly clicking but event not registering

Swift3/iOS10/Xcode8

我有一个视图控制器 (pieChart),其中包含一个标签、两个按钮和一个空视图(其中将包含一个饼图)。标签和两个按钮合并到水平堆栈视图中,位于饼图视图上方。

上面的VC在应用程序启动时嵌入到四个容器视图之一(应用程序的主屏幕由这四个容器视图组成)。

在 pieChart 中,我将两个按钮链接到它们各自的 IBActions 和 IBOutlets。单击按钮 2 时,另一个 VC 应该会出现模态转场,但这并没有发生。可见,按钮正在记录点击 - 即当您点击它时它会改变颜色。我在按钮 2 的 IBAction 方法中放置了一个打印语句,但这也没有显示。控制台中也没有显示错误消息。

经过几个小时的搜寻,我发现发生这种情况的唯一原因是:

  1. 子视图已添加到按钮本身,因此点击事件信号会通过按钮并由添加的子视图接收。这不是我的情况。顺序是 Main App Window > Container View > Embedded VC > Stack View > Button。 InteractionEnabled 对所有设置为 true。

  2. 按钮部分位于包含视图之外(它 height/width 可能大于其包含视图)。 我不是这种情况。 stack view、label和两个button共享相同的高度,stack view的宽度等于label和button的宽度加上label和button之间的间距。

我还尝试通过以下方式以编程方式添加事件处理程序:

SelectAnalyisButtonOutlet.addTarget(self, action: #selector(SelectAnalysisButtonClicked), for: .touchUpInside)

但结果相同。

是否有其他原因导致点击事件似乎没有注册?

编辑 1

上面提到的饼图 VC 是从同一容器视图(称为 detailContainerView)换出的几个 VC 之一,具体取决于哪个按钮(所有这些都工作得很好) 在 OTHER 容器视图之一(称为 TabBar)中单击。

我在其他两个显示在 detailContainerView 中的 VC 中分别放置了一个按钮,并将它们分别连接到一个 IBAction。每个 IBAction 都包含一个在单击按钮时触发的打印语句。那么目前这两个VC只是一个标签和新插入的按钮组成。 None 个按钮在我 运行 应用程序时起作用。

然后我将 VC 的 detailContainerView 之一设置为属性检查器中的初始视图控制器,然后重新 运行 应用程序。突然,按钮现在可以工作了!如果我然后将按钮连接到 segue,segue 也可以工作!

当我换出 detailContainerView 中的 VC 时,情况似乎发生了变化。我用来交换 VC 的代码如下:

    func SwapOutControllers(vc: UIViewController, vcName: String){

    //REMOVE OLD VC
    detailPaneVCReference?.willMove(toParentViewController: nil)
    detailPaneVCReference?.view.removeFromSuperview()
    detailPaneVCReference?.removeFromParentViewController()

    var newVc: UIViewController?

    switch vcName {
    case "Biography":
        newVc = vc as! Biography

    case "Social Media":
        newVc = vc as! SocialMedia

    case "News Feed":
        newVc = vc as! NewsFeeds

    case "Stats":
        newVc = vc as! StatsAboutParliament

    case "Petitions":
        newVc = vc as! Petitions

    default:
        print("Error: No VC Found!")
    }

    //ADD NEW VC
    ParentVC?.addChildViewController(newVc!)

    let width = detailContainerView?.frame.width
    let height = detailContainerView?.frame.height

    newVc?.view.frame = CGRect(x: 0, y: 0, width: width!, height: height!)

    detailContainerView?.addSubview((newVc?.view)!)

    newVc?.didMove(toParentViewController: ParentVC)

}

detailPaneVCReference 是对 detailContainerView 当前正在显示的任何 VC 的引用。 ParentVC 是包含四个容器视图的 VC。

从 ParentVC 中移除的 VC 在被 removed/swapped 移除后仍然存在于调试视图层次结构中 - 这是否会以某种方式阻止点击事件到达事件处理程序?

解决方案!

我的问题的根源是我对每个在 detailContainerView 中换入和换出的视图控制器的引用被错误地声明为弱引用。我从每个声明中删除了 "weak"(例如 "weak var x: UIViewController?" --> "var x: UIViewController?"),瞧!代码现在按预期工作了!

我的问题的根源是我对每个在 detailContainerView 中换入换出的视图控制器的引用被错误地声明为弱引用。我从每个声明中删除了 "weak"(例如 "weak var x: UIViewController?" --> "var x: UIViewController?"),瞧!代码现在按预期工作了!