web-dev-qa-db-ja.com

xibのカスタムクラスからデリゲートを接続する方法は?

デリゲートと呼ばれるプロパティを介して「DeletableImageViewDelegate」として定義したプロトコルを使用するクラス「DeletableImageView」(。Swift + .xib)を作成しました。

わかりやすくするための例:

DeletableImageView.Swift

protocol DeletableImageViewDelegate {
    func deleteImageWithTag(tag: Int!) -> (Bool)
    func addImageOnViewWithTag(tag: Int!) -> (Bool)
    ...
}

class DeletableImageView: UIView {

    var view: UIView!
    var delegate: DeletableImageViewDelegate?

    // Some random methods + some use of the delegate protocol's methods
    ...
}

私の問題は、関連付けられた.xibファイルからコントローラーでクラスを使用しようとすると(つまり、Interface Builderでビューをドラッグアンドドロップし、DeletableImageViewクラスをこのビューに割り当てる)、デリゲートプロパティをリンクできないことです。 (このプロパティをIBOutletとして宣言した場合でも)。

私ができるようにしたいのは、直接ビューのデリゲートアウトレットを.xibの「ファイルの所有者」にリンクする

データソースをリンクし、テーブルビューから直接.xibファイルに委任する場合とまったく同じことです。

しかし、私がコントロールドラッグすると、それらは一緒にリンクされません。

誰かが何が起こっているのかについて何か考えがありますか?

どうもありがとうございました。

14
Matthieu luci

最初に行う必要があるのは、プロトコル定義から@objcを追加して、次のようにすることです。

@objc protocol DeletableImageViewDelegate {
    ...
}

なぜこれを行う必要があるのか​​と疑問に思うかもしれません。ストーリーボードにデリゲートプロパティを追加する必要があるためです。ストーリーボードで表示されるプロパティを設定するには、@IBOutletプレフィックスが必要であり、そのプレフィックスにはObjectiveCプロトコルである必要があります。

したがって、次に実行したいのは、var delegate: DeletableImageViewDelegate?をに変更することです。

@IBOutlet var delegate: DeletableImageViewDelegate?

これで、Interface Builderのビューを右クリックすると、次のようなものが表示されます。これは、デリゲートプロパティをInterfaceBuilderに公開したことを意味します。 Exposed property

ファイル所有者(たとえば、UIViewController)に接続しようとしても、ファイル所有者がまだそのプロトコルを実装していないため、機能しません。それを実装するには、次のように書く必要があります。

extension UIViewController : DeletableImageViewDelegate {
    // Implementation
}

これを行うと、デリゲートプロパティをView Controllerに接続できるようになり、デリゲートメソッドメッセージを受信できるようになります。いずれの場合も、ファイル所有者はプロトコルを実装する必要があります。

4
Said Sikira

コメントと同様のソリューションを作成しました。しかし、毎回デリゲートをキャストしてプロトコルの実装を確認する必要もありませんでした。

weak var delegate: MenuViewDelegate?
@IBOutlet weak var _delegate: AnyObject? {
    didSet {
        if let d = _delegate {
            if let d = (d as? MenuViewDelegate) {
                delegate = d
            } else {
                print("ERROR: delegate does not implement \(d) MenuViewDelegate protocol")

                d as! MenuViewDelegate
            }
        }
    }
}
0
Dracris