Подтвердить что ты не робот

Быстрый протокол, свойство IBOutlet не может иметь неъектный тип

Я хотел бы подключить пользовательский быстрый делегат в IB. Делегат - это объект, который быстро реализует определенный протокол.

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?
    ^~~~~~~~~
4b9b3361

Ответ 1

Вы должны объявить свой ThumbnailTableViewCellDelegate протокол как @objc:

@objc protocol ThumbnailTableViewCellDelegate {
    func cellWasTouched(thumbnail: Bool, cell: UITableViewCell)
}

Это потому, что @IBOutlet объявляет переменную как weak, которая работает только с объектами. Я не уверен, почему вы не можете просто сказать, что протокол соответствует AnyObject, возможно, что ошибка Swift.

Ответ 2

Вы можете связать свои собственные протоколы в IB с этим обходным решением. Это известная проблема с Xcode, поэтому, вероятно, она будет решена в один прекрасный день. До тех пор:

  • Объявить делегата как AnyObject - @IBOutlet var delegate: AnyObject!
  • Подключить делегат в Interface Builder
  • Измените тип выхода на свой протокол, например. @IBOutlet var delegate: MyDelegate

Это работает для меня.

Ответ 3

Переменная типа протокола может не быть объектом, потому что структуры и перечисления могут также соответствовать протоколам. Чтобы гарантировать соответствие протокола только классам, вы можете объявить протокол с помощью @class_protocol.

Ответ 4

Не идеально, но вариант состоит в том, чтобы сделать что-то вроде этого:

@IBOutlet var objectType: NSObject!

private var conformingObject: SomeProtocol {
  return objectType as SomeProtocol
}

Чтобы убедиться, что ваш objectType соответствует SomeProtocol или все взорвутся

Ответ 5

Как бы то ни было, 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))
}

Ответ 6

IBOutlets должны указывать указатель на объект, хранящийся в файле nib (или раскадровки). Протокол не является объектом, поэтому вы не можете иметь его в файле nib. Сделайте тип IBOutlet var типом фактического объекта, который у вас есть в nib.