斯威夫特 3/iOS 10/Xcode 8
我有一个包含标签、两个按钮和一个空视图(将包含一个饼图)的视图控制器(pieChart)。标签和两个按钮被合并到一个水平堆栈视图中,它位于饼图视图上方。
当应用程序启动时,上述 VC 嵌入到四个容器视图之一(应用程序的主屏幕由这四个容器视图组成)。
在 pieChart 中,我已将两个按钮链接到它们各自的 IBActions 和 IBOutlets。单击按钮 2 时,另一个 VC 应该会出现模态转场,但这不会发生。可见,该按钮正在注册单击 - 即,当您单击它时它会改变颜色。我在按钮 2 的 IBAction 方法中放置了一个打印语句,但这也没有显示。控制台中也不会显示任何错误消息。
经过几个小时的狩猎,我发现发生这种情况的唯一原因是:
子视图已添加到按钮本身,因此单击事件信号会经过按钮以被添加的子视图接收。这不是我的情况。顺序是主应用程序窗口 > 容器视图 > 嵌入式 VC > 堆栈视图 > 按钮。所有人的 InteractionEnabled 都设置为 true。
按钮部分位于包含视图之外(它的高度/宽度可能大于其包含视图)。这不是我的情况。堆栈视图、标签和两个按钮共享相同的高度,堆栈视图的宽度等于标签和按钮的宽度之和加上标签和按钮之间的间距。
我还尝试使用以下方式以编程方式添加事件处理程序:
SelectAnalyisButtonOutlet.addTarget(self, action: #selector(SelectAnalysisButtonClicked), for: .touchUpInside)
但同样的结果也会发生。
点击事件似乎没有注册还有其他原因吗?
编辑 1
上面提到的 pieChart VC 是从同一个容器视图(称为 detailContainerView)中交换出来的几个 VC 之一,这取决于在其他容器视图之一(称为 TabBar)中单击了哪个按钮(所有这些都可以正常工作)。
我在 detailContainerView 中显示的另外两个 VC 中分别放置了一个按钮,并将它们分别连接到 IBAction。每个 IBAction 都包含一个在单击按钮时触发的打印语句。目前,这两个 VC 只包含一个标签和新插入的按钮。当我运行应用程序时,所有按钮都不起作用。
然后我将 detailContainerView 的 VC 之一设置为属性检查器中的初始视图控制器并重新运行应用程序。突然,按钮现在起作用了!如果我然后将按钮连接到 segue,segues 也可以工作!
当我在 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 在被删除/换出后仍然存在于调试视图层次结构中 - 这是否会以某种方式阻止点击事件到达事件处理程序?
解决方案!
我的问题的根源是我对每个视图控制器的引用被错误地声明为弱引用,这些视图控制器被交换进和交换出 detailContainerView。我从每个声明中删除了“weak”(例如“weak var x: UIViewController?”->“var x: UIViewController?”),瞧!代码现在可以按预期工作了!