【发布时间】:2017-10-23 06:21:24
【问题描述】:
我正在创建一个自定义呈现控制器,用于在呈现视图控制器时使背景变暗。演示控制器在过渡开始时添加了几个子视图,效果很好。
但是,我想在 Interface Builder 中设置 chrome(演示文稿“框架”),因为这样布局更容易。因此,我创建了一个用于设计 chrome 的 XIB 文件。它包括一个半透明的背景视图和左上角的 ❌ 按钮,用于关闭呈现的视图控制器。对于这些子视图我需要在我的演示控制器中使用插座和操作(这不是UIViewController 子类)。
为了实现这一点,我在 Interface Builder 和实例化视图时的代码中将 XIB 文件的所有者设置为我的自定义演示控制器:
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 的类创建出口和操作。
这个假设正确吗?
有没有办法使用非视图(-控制器)类创建出口和操作?
【问题讨论】:
-
听起来您需要将“ChromeView”实例化为子视图控制器......然后使用委托模式将“X 按钮”点击“传递给执行实际演示的视图控制器”。
-
如果我不让它运行,我会退回到这种模式。但是,如果@floschliep 是正确的您可以在任何继承自 NSObject 的类中创建 IBOutlets,那么我只是想知道为什么这种方法不起作用。
-
嗯,创建 IBOutlets 和实例化连接这些出口的代码是有区别的。我对你的结构有点困惑?您在 XIB 中有一个 UIView + UIButton ... XIB 的所有者 不是 UIView 或 UIViewController 子类?问题是...如果您所做的只是从 XIB 加载 UIView(和子视图),但您不加载/实例化与其关联的代码,则 IBOutlet 和 IBAction 不存在.
-
嗯...我重新阅读了您的问题,现在我有点困惑...您说您将 XIB 文件的所有者设置为“自定义演示控制器”-但是 那个 控制器不是
UIView或UIViewController子类?你能举一个小例子来说明你在做什么(并抛出错误)吗? -
是的,这正是问题所在:是否可以将
UIView或UIViewController子类以外的类设置为视图的文件所有者(以便在那里创建出口和操作) ?
标签: ios uiview ibaction iboutlet uipresentationcontroller