Interface Builder,@ IBOutlet以及Swift中delegate和dataSource的协议

时间:2014-10-03 13:52:32

标签: swift interface-builder iboutlet

无法将声明为@IBOutlet的CustomView的委托属性连接到Interface Builder中的ViewController - 根本无法建立连接。

这是代码

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

@objc protocol CustomViewDelegate {
     ...
}


class ViewController: UIViewController, CustomViewDelegate {
     ...
}
由于swift protocol, IBOutlet property cannot have non-object type使用

@objc,因此不知道为什么protocol CustomViewDelegate: class {}无效。

其他人遇到过类似的事情吗?

6 个答案:

答案 0 :(得分:58)

从Xcode发行说明:

  当插座的类型是协议时,

Interface Builder不支持连接到Swift文件中的插座。

     

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

编辑: Xcode 9 beta 3发行说明说不再需要这种解决方法。

答案 1 :(得分:15)

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 {
    ...
}
嘿,这个小虫已经有一年半了吗?

答案 2 :(得分:9)

优雅的解决方法:

#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

答案 3 :(得分:8)

另一个并不漂亮,但是:

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

答案 4 :(得分:3)

这是一个老线程,但我想我会指出,从Xcode 9 beta 3开始,现在可以将用swift编写的自定义委托连接到界面构建器。

根据发行说明

  

Interface Builder现在可识别出口,操作和可检查   在具有Swift协议扩展的类上声明的属性。   (22201035)

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

答案 5 :(得分:1)

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