在Swift中Interface Builder,@IBOutlet和委托和数据源协议

问题描述:

无法在Interface Builder中将声明为@IBOutlet的CustomView的代理属性连接到ViewController - 无法建立连接。在Swift中Interface Builder,@IBOutlet和委托和数据源协议

下面的代码

class CustomView: UIView { 
    @IBOutlet var delegate: CustomViewDelegate? 
} 

@objc protocol CustomViewDelegate { 
    ... 
} 


class ViewController: UIViewController, CustomViewDelegate { 
    ... 
} 

@objc被使用,因为swift protocol, IBOutlet property cannot have non-object type,不知道为什么protocol CustomViewDelegate: class {}不起作用。

其他人碰到类似的东西?

+0

贵'UIViewController'在Interface Builder具有同级车专门设置为'ViewController'?此外,它通常是一个要求(最后我检查),“@ IBOutlet”属性被定义为隐式解包类型,如下所示:“CustomViewDelegate!”。这允许它们在实例化时为'nil',同时允许您在连接完成后无需绑定就可以使用它们。 – 2014-10-03 13:58:16

从Xcode的版本注释:

界面生成器不支持连接到出口以迅速文件当出口的类型是一个协议。

解决方法:将出口的类型声明为AnyObject或NSObject,使用Interface Builder将对象连接到出口,然后将出口的类型更改回协议。

编辑:的Xcode 9 Beta 3的发布说明称,这一解决办法应该不再是必要的。

+3

Wowzer!这工作,谢谢。苹果...请把它放在一起! – josephap 2015-03-09 01:22:26

+0

没有。更改回协议类型后,“类不符合键值”。 – stone 2015-03-15 12:48:01

+0

这只对我有效。在一种情况下,我在UIView上定义了我自己的委托,将其连接到UIViewController,它工作。在另一个地方,我在UIViewController上定义我的委托以连接到另一个UIViewController,但它没有。我尝试了很多配置。任何想法@matt可能会在这里发生什么? – josephap 2015-03-15 21:50:02

另一种是不漂亮,但:

@IBOutlet weak var ibDelegate: NSObject? 
@IBOutlet weak var ibDataSource: NSObject? 
var delegate: MultipleButtonViewDelegate? { return ibDelegate as? MultipleButtonViewDelegate } 
var dataSource: MultipleButtonViewDataSource? { return ibDataSource as? MultipleButtonViewDataSource } 
+0

很好的答案!使用这种方法来防止更改类型通常是出口。 – t4nhpt 2016-01-06 06:46:43

Adam Waite provides a nice workaround.但是我更喜欢下面的解决方案,它强调的是解决办法,一旦Xcode中得到固定,也容易去除多余的财产。

class CustomView: UIView { 
    @IBOutlet 
    public var delegate: CustomViewDelegate? 

    /// Workaround for Xcode bug that prevents you from connecting the delegate in the storyboard. 
    /// Remove this extra property once Xcode gets fixed. 
    @IBOutlet 
    public var ibDelegate: AnyObject? { 
     get { return delegate } 
     set { delegate = newValue as? CustomViewDelegate } 
    } 

    func someMethod() { 
     // Here we always refer to `delegate`, not `ibDelegate` 
     delegate?.onSomethingHappened() 
    } 
} 

@objc protocol CustomViewDelegate { 
    ... 
} 

嘿,这个bug已经多年的一个半老?

对我来说,原因是表格视图是nil在我试图设置它的数据源和委托。这是由于指定的初始化程序调用initWithNibName:bundle:,它不保证initialized connections。推迟我的代表和数据源设置为viewDidload就像一个魅力。

优雅的解决方法:

#if TARGET_INTERFACE_BUILDER 
@IBOutlet open weak var delegate: AnyObject? 
#else 
open weak var delegate: CustomViewDelegate? 
#endif 

参见: https://github.com/WenchaoD/FSPagerView/blob/master/Sources/FSPagerView.swift#L88

这是一个古老的线程,但我想我会指出,作为Xcode的9测试版3中,现在可以将用swift编写的自定义委托连接到界面构建器。

根据发行说明

界面生成器现在可以识别网点,动作,以及其拥有斯威夫特协议扩展类中声明视察 性能。 (22201035)

// Can connect this to interface builder now  
class MyViewController: UIViewController { 
    @IBOutlet weak var myDelegate: TheNewDelegate? 
}