2014-07-03 15 views
14

Tôi muốn kết nối đại biểu nhanh chóng tùy chỉnh trong IB. Các đại biểu là một đối tượng thực hiện một giao thức nhất định trong nhanh chóng.giao thức nhanh, thuộc tính IBOutlet không thể có loại đối tượng

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

class ThumbnailTableViewCell: UITableViewCell { 
    @IBOutlet var thumbnailTableViewCellDelegate: ThumbnailTableViewCellDelegate? 
} 

không may, trình biên dịch phàn nàn với:

error: 'IBOutlet' property cannot have non-object type 'ThumbnailTableViewCellDelegate' 
    @IBOutlet var thumbnailTableViewCellDelegate: ThumbnailTableViewCellDelegate? 
    ^~~~~~~~~ 
+3

@Andy Hoàn toàn ổn - bạn đang nói đó là một đối tượng phù hợp với giao thức đó. –

Trả lời

27

Bạn phải khai báo của bạn ThumbnailTableViewCellDelegate giao thức như @objc:

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

này được vì @IBOutlet tuyên bố biến như weak, mà chỉ làm việc với các đối tượng. Tôi không chắc tại sao bạn không thể nói giao thức tuân theo AnyObject, có lẽ đó là lỗi Swift.

+0

Cảm ơn Nate, đã làm việc!Đây có phải là giải pháp tạm thời hoặc hành vi dự kiến ​​không? Sự liên quan của @objc trong trường hợp này là gì? – pixbroker

+1

Phương pháp này không còn hoạt động cho tôi nữa (sử dụng hạt giống GM của Xcode 6.) – Ash

+9

Biên dịch này nhưng tôi đang gặp sự cố khi kết nối ổ cắm trong bảng phân cảnh bây giờ –

-1

IBOutlets phải chỉ ra con trỏ tới đối tượng được lưu trữ trong tệp nib (hoặc bảng phân cảnh). Một giao thức không phải là một đối tượng, do đó bạn không thể có một trong một tệp nib. Làm cho kiểu IBOutlet var là kiểu đối tượng thực tế bạn có trong nib.

0

Biến kiểu giao thức có thể không phải là một đối tượng, vì cấu trúc và enums có thể phù hợp với các giao thức. Để đảm bảo rằng một giao thức chỉ có thể được tuân theo các lớp, bạn có thể khai báo giao thức với @class_protocol.

0

Không lý tưởng, nhưng là một lựa chọn là để làm một cái gì đó như thế này:

@IBOutlet var objectType: NSObject! 

private var conformingObject: SomeProtocol { 
    return objectType as SomeProtocol 
} 

Got để đảm bảo objectType của bạn phù hợp với SomeProtocol hoặc những thứ sẽ nổ

14

Bạn ở có thể kết nối các giao thức của riêng bạn trong IB với cách giải quyết này. Đó là một vấn đề đã biết với Xcode, vì vậy có thể sẽ được giải quyết một ngày. Cho đến lúc đó:

  1. Tuyên bố đại biểu dưới dạng AnyObject - @IBOutlet var delegate: AnyObject!
  2. Kết nối đại biểu trong Trình tạo giao diện
  3. Thay đổi loại của trình cắm cho giao thức của bạn, ví dụ: @IBOutlet var delegate: MyDelegate

Điều này phù hợp với tôi.

+0

Có một radar hoặc bản phát hành đã biết nào được ghi lại không? –

0

Có nghĩa là IB yêu cầu AnyObject, thay vì giao thức cụ thể của bạn. Các đối tượng bạn muốn kết nối để có thể, nhưng không nhất thiết phải phù hợp với các giao thức, và các giao thức có thể có optionals - vậy:

Hãy giao thức của bạn như thế này:

@objc public protocol HexViewDataSource: NSObjectProtocol { 
    @objc optional func dataAtOffset (_ hexView: HexView, offset: UInt64, length: Int)-> Data? 
    @objc optional func dataLength (_ hexView: HexView) -> UInt64 
} 

Khai báo nó trong lớp học của bạn như thế này Ví dụ:

@IBOutlet weak open var dataSource: AnyObject? 

và khi bạn đến để sử dụng nó, kiểm tra xem nó phù hợp với các giao thức và rằng optionals tồn tại - như thế này:

if let dataSource = dataSource as? HexViewDataSource, let dfr = dataSource.dataAtOffset { 
    setRowData(offset: offset, data: dfr (self, offset, bytesPerRow)) 
} 
Các vấn đề liên quan