我想在IB中连接一个自定义快速代表。委托是一个在swift中实现某个协议的对象。
protocol ThumbnailTableViewCellDelegate {
func cellWasTouched(thumbnail: Bool, cell: UITableViewCell)
}
class ThumbnailTableViewCell: UITableViewCell {
@IBOutlet var thumbnailTableViewCellDelegate: ThumbnailTableViewCellDelegate?
}
不幸的是,编译器抱怨:
error: 'IBOutlet' property cannot have non-object type 'ThumbnailTableViewCellDelegate'
@IBOutlet var thumbnailTableViewCellDelegate: ThumbnailTableViewCellDelegate?
^~~~~~~~~
答案 0 :(得分:31)
您必须将ThumbnailTableViewCellDelegate
协议声明为@objc
:
@objc protocol ThumbnailTableViewCellDelegate {
func cellWasTouched(thumbnail: Bool, cell: UITableViewCell)
}
这是因为@IBOutlet
将变量声明为weak
,它只适用于对象。我不确定为什么你不能说协议符合AnyObject
,也许这是一个Swift bug。
答案 1 :(得分:14)
您可以使用此解决方法将IB中自己的协议连接起来。这是Xcode的一个已知问题,所以有一天可能会解决。在那之前:
这适合我。
答案 2 :(得分:1)
不理想,但选择是做这样的事情:
@IBOutlet var objectType: NSObject!
private var conformingObject: SomeProtocol {
return objectType as SomeProtocol
}
确保您的objectType
符合SomeProtocol
或事情会爆炸
答案 3 :(得分:0)
协议类型的变量可能不是对象,因为结构和枚举也可以符合协议。要确保协议只能按类符合,您可以使用@class_protocol
声明协议。
答案 4 :(得分:0)
IB需要AnyObject而不是您的特定协议才有意义。您想要连接的对象可能但不一定符合协议,协议可能包含选项 - 所以:
使您的协议如下:
@objc public protocol HexViewDataSource: NSObjectProtocol {
@objc optional func dataAtOffset (_ hexView: HexView, offset: UInt64, length: Int)-> Data?
@objc optional func dataLength (_ hexView: HexView) -> UInt64
}
在你的类中声明它,例如:
@IBOutlet weak open var dataSource: AnyObject?
当你使用它时,检查它是否符合协议并且选项存在 - 如下所示:
if let dataSource = dataSource as? HexViewDataSource, let dfr = dataSource.dataAtOffset {
setRowData(offset: offset, data: dfr (self, offset, bytesPerRow))
}
答案 5 :(得分:-1)
IBOutlets用于指示指向存储在nib(或storyboard)文件中的对象的指针。协议不是对象,因此您不能在nib文件中拥有一个协议。使IBOutlet var的类型为nib中实际对象的类型。