※この記事は4年以上前の記事です。
現在は状況が異なる可能性がありますのでご注意ください。
どうも。
すっかりどっぷりSwift浸かってるみやびです。
だいぶ慣れたが、やっぱ制約とかあって難しいわ、オブジェクト指向言語・・・。
(というか、Swiftの場合、とにかくストーリーボードとオートレイアウトがうざい。←マジで滅べ)
さて、表記の件だが、
通常、デリゲートメソッドを指定する場合、
処理譲渡先に、必ずデリゲートメソッドを記述しなくてはならないが、
今回は、必須で書かなくてもよくする方法を紹介したい。
デリゲートメソッドってなんぞやって人は下記をご参照されたし。
(めんどくさい説明は他者に任せるスタイル)
●【Swift入門】難解なデリゲート(delegate)の使い方を理解しよう!
例えば、下記のような、二つのクラスがあるとする。
// デリゲート元 import UIKit protocol AclassDelegate { func testFunc(_ image: UIImage?) } class A { var delegate: AclassDelegate? = nil init(){ } func testRun(){ let testImage = UIImage() self.delegate?.testFunc(testImage) } }
// デリゲート先 import UIKit class B: AclassDelegate { var aInstanse: A = A() init(){ self.aInstanse.delegate = self } // デリゲートメソッドを記載しなければいけない func testFunc(_ image: UIImage?) { // 処理内容 } }
クラスBでは、Aのデリゲートを継承しているが、
この場合、クラスB内で、必ずデリゲートメソッドを全て記述しなくてはならない。
いいんだけど、めんどうというか、余計な記述しなきゃいけない時があるから、
少々不便だ。
だが、よく考えれば、例えば、UITableViewのデリゲートメソッドとか、各種既存クラスでは、
必須でないデリゲートメソッドが存在する。
例えば下記。
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int { return 5 }
したらカスタムクラスでもできんじゃね?
ってことで調べてみたが、これが出ない出ない。
調べ方がいけなかったか、本当に出てこなかった。
ってことで、奥の手、teratailで質問した結果、
下記の方法を教えてくれた。
extension AclassDelegate { func testFunc(_ image: UIImage?) {} }
つまり、プロトコルを拡張して、ダミー関数を追加するというもの。
うん、実装できた。
おそらくこれが一番いい方法。
fuzzballさん、本当にありがとうございます。大感謝。
して、実はもう一個の方法がある。
UITableViewなどと同じ方法をとる方法だ。
UITableViewのデリゲートは下記のように定義されている。
public protocol UITableViewDataSource : NSObjectProtocol { public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell // 必須 optional public func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int // 非必須 }
optionalキーワードで定義すれば、非必須にできるようだ。
これを参考に、Swift4で定義すると下記になる。
@objc protocol AclassDelegate: NSObjectProtocol { @objc optional func testFunc(_ image: UIImage?) }
どうやら、@objcを使って無理やりなのであまり推奨されはしないようだ。
だが、既存クラスと同じ仕様でやれるのはスマートな方法ではないだろうか。
こちらの方法は、tyobigoroさんが教えてくれた。
こちらも大変に感謝です。
やっぱ、あれだね、わかる人に聞いた方が早いね。
Google先生と対話するのもいいんだけど、
的外れな記事ばかり出ると、イライラしかしないし、時間ももったいないしね。
さて、今日もオートレイアウトとの格闘が続くか・・・。
コメントする