我想在IB中连接一个自定义swift委托,该委托是在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?
^~~~~~~~~
您必须将您的ThumbnailTableViewCellDelegate
协议声明为@objc
:
@objc protocol ThumbnailTableViewCellDelegate {
func cellWasTouched(thumbnail: Bool, cell: UITableViewCell)
}
这是因为@IBOutlet
将变量声明为weak
,它只对对象起作用。我不知道为什么你不能说协议符合AnyObject
,也许这是一个Swift的错误。
您可以使用此解决方案在IB中连接自己的协议。这是Xcode的一个已知问题,所以有一天可能会得到解决。在那之前:
- 将委托声明为AnyObject - @IBOutlet var delegate:AnyObject!
- 在Interface Builder中连接委托
- 将outlet的类型更改为你的协议,例如@IBOutlet var delegate:MyDelegate
不理想,但可以这样做:
@IBOutlet var objectType: NSObject!
private var conformingObject: SomeProtocol {
return objectType as SomeProtocol
}
必须确保你的objectType
和SomeProtocol
一致,否则事情会爆炸
协议类型的变量可能不是对象,因为结构体和枚举也可以符合协议。为了确保协议只能被类遵守,您可以使用@class_protocol
声明该协议。
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))
}
2023…
您只需在协议定义之前添加@objc
。
不需要在视图控制器中做任何修改
的例子:
@objc protocol VideoControls {
var playButton: UIButton! { get }
var pauseButton: UIButton! { get }
var timeText: UILabel! { get }
然后在视图控制器中。
class CompactPlayer: UIViewController, VideoControls {
@IBOutlet var playButton: UIButton!
@IBOutlet var pauseButton: UIButton!
@IBOutlet var timeText: UILabel!
和
class FullScreenPlayer: UIViewController, VideoControls {
@IBOutlet var playButton: UIButton!
@IBOutlet var pauseButton: UIButton!
@IBOutlet var timeText: UILabel!
。
iboutlet是指向存储在nib(或storyboard)文件中的对象的指针。协议不是对象,因此你不能在nib文件中拥有一个。使IBOutlet变量的类型成为nib中实际对象的类型。