我创建了一个自定义演示控制器,用于在显示视图控制器时调暗背景。演示控制器在转换开始时添加了几个子视图,效果很好。
但是,我想在 Interface Builder 中设置chrome(演示文稿" frame"),因为这样更容易布局。因此,我创建了一个用于设计chrome的XIB文件。它包括一个半透明的背景视图和左上角的❌按钮,以关闭呈现的视图控制器。对于这些子视图我需要在演示文稿控制器中使用插座和操作(不是一个UIViewController
子类)。
为了实现这一点,我将XIB的文件所有者设置为我的自定义表示控制器,在实例化视图时在Interface Builder和代码中设置:
lazy var dimmingView = Bundle.main.loadNibNamed("PresentationChromeView",
owner: self,
options: nil)?.first
as! UIView
然后我通过 CTRL +拖动到我的演示控制器创建了各自的出口和动作:
@IBOutlet var closeButton: UIButton!
@IBAction func closeButtonTapped(_ sender: Any) {
presentingViewController.dismiss(animated: true, completion: nil)
}
但是,在运行时,应用程序崩溃是因为UIKit无法找到插座键,并且在删除插座时不会触发操作方法。所以在两种情况下都没有建立连接。
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<_SwiftValue 0x600000458810> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key closeButton.'
我能想到为什么这不起作用的唯一原因是它不允许使用不能从UIView
继承的类创建出口和操作。 UIViewController
。
有没有办法用非视图(-controller)类创建出口和操作?
答案 0 :(得分:2)
您可以在继承自NSObject
的任何类中创建IBOutlet。这里的问题似乎是您没有在界面构建器中设置自定义类:
'[<NSObject 0x60800001a940> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key closeButton.'
解码你的笔尖时,NSCoder
尝试在closeButton
的实例上设置NSObject
属性,当然这个属性没有这个属性。您未指定自定义类或无效连接。
答案 1 :(得分:0)
好的......主要问题是必须实例化XIB / NIB文件,而不仅仅是加载第一个项目。
所有这些更改都在DimmingPresentationController.swift
:
// don't load it here...
//lazy var dimmingView = Bundle.main.loadNibNamed("DimmedPresentationView", owner: self, options: nil)?.first as! UIView
var dimmingView: UIView!
...然后
private func addAndSetupSubviews() {
guard let presentedView = presentedView else {
return
}
// Create a UINib object for a nib (in the main bundle)
let nib = UINib(nibName: "DimmedPresentationView", bundle: nil)
// Instante the objects in the UINib
let topLevelObjects = nib.instantiate(withOwner: self, options: nil)
// Use the top level objects directly...
guard let v = topLevelObjects[0] as? UIView else {
return
}
dimmingView = v
// add the dimming view - to the presentedView - below any of the presentedView's subviews
presentedView.insertSubview(dimmingView, at: 0)
dimmingView.alpha = 0
dimmingView.frame = presentingViewController.view.bounds
}
应该这样做。如果它不适合你,我可以在你的GitHub回购中添加一个分支(很确定我没有做任何其他更改)。
答案 2 :(得分:0)
导致应用崩溃的问题是无法推断出dimmingView
类型(这很奇怪,因为编译器没有抱怨) 。将显式类型注释添加到属性的声明中可以修复崩溃。所以我只是替换了这一行
lazy var dimmingView = Bundle.main.loadNibNamed("PresentationChromeView",
owner: self,
options: nil)?.first
as! UIView
用那一行:
lazy var dimmingView: UIView = Bundle.main.loadNibNamed("PresentationChromeView",
owner: self,
options: nil)?.first
as! UIView
出口和行动现已正确连接。
为什么这种类型的推理没有用,或者为什么这个问题解决了这个问题对我来说仍然是一个谜,我仍然可以解释。 ❓