我正在尝试一种无故事板的方法,并尝试了以下方法:


我创建了一个FooView.xib来保存我的布局。它具有一些按钮和标签。
我创建了一个FooView.swift来保存UIView的FooView子类。目前,它实际上什么也没做。
我创建了FooViewController.swift来管理我的FooView实例。我称其为创建FooViews如下:

在里面() {
    super.init(nibName:“ FooView”,包:nil)
}
我将FooView.xib的文件所有者设置为FooView类
我将FooView视图的自定义类设置为FooView
我将一些@IBAction输出从IB拖动到FooView实现中


当我的动作触发时,我得到一个运行时异常:“无法识别的选择器发送到实例”,该异常引用了FooViewController(!)。我仔细检查了文件所有者和所有输出,所有引用看起来正确。

就像在事件分发方面忽略文件所有者一样。

(感觉就像我在与框架作斗争,确实希望在控制器内实现我的所有输出/动作,但是从架构纯净度的角度(以增强测试),我倾向于隐藏xib控件的细节并使之更加不透明。不会直接向控制器公开其内部控件的视图,而是具有协议/委托类型的合同。)

我有一个偷偷摸摸的怀疑,如果我将所有xib-loading逻辑移到UIView实现中,一切都会奏效,但这听起来像是一次更大的冒险。有没有简单的方法来设置FooView子类以接收事件?

最佳答案

您可以使用的另一种方法是将“第一响应者”设置为操作目标。尽管您不会在IBAction所连接的XCode中获得漂亮的整洁指示符,但它会将消息传递给实现该方法的响应者链中的第一类。

要在界面构建器中进行设置,请单击“第一响应者”并打开“属性”检查器。将您的方法作为someAction:添加到“用户定义”列表中(不要忘记冒号)。然后,您可以将按钮连接到第一响应者,该方法将是您进行连接的可用选项。

最后,您像要在其中实现它的视图类中的正常声明IBAction一样。

10-06 11:32