例えば、(A)UIViewがタッチされた時に、delegateを用いて(B)BViewController、(C)CViewControllerに処理をさせたいとします。
class (A)UIView { weak var delegate: UIViewDelegate? @objc touchB { delegate?.didTouchB() } @objc touchC { delegate?.didTouchC() } }
protocol UIViewDelegate: AnyObject { func didTouchForB() func didTouchForC() }
class BViewController: UIViewDelegate { func didTouchForB() { print("B") } }
class CViewController: UIViewDelegate { func didTouchForC() { print("C") } }
以上のようなコードのとき、BViewControllerには func didTouchForC()が書かれてないとエラーが出ます。
BViewControllerにその処理は必要ないのですが、エラーに従ってfunc didTouchForC()を書かなければならないのでしょうか。
BViewControllerにdidTouchForC()を書かなくて済むようなコードの書き方があれば教えていただきたいと思います。
※delegateの使い方はこれ以外知識がありません。
protocolをもう一つ作る方法も思いつきましたが、いかがでしょうか。
よろしくお願いいたします。
protocolのextensionを使って共通メソッドを定義する方法を調べてみてください。
protocol SearchBarDelegate: AnyObject {
func didTouchSearchButton(word: String)
}
extension SearchBarDelegate where Self: BViewController {
func textFieldisBlank() {
print("TextFieldは空白です")
}
}
このようにして、BViewControllerに対しprotocolを追加してみました。
私の解釈では、共通メソッドはwhereで指定する型に対しメソッドをprotocol内で追加することによって、その型は追加されたメソッドを使えるようになるものである、と考えております。
型に対し、extensionさせるとそのメソッドを使わないような場面においてもメソッドが選択肢として出てしまうため、使いたい場面において任意にprotocolに準拠させることでそれを防いでいるという感じです。
参考(http://www.kuma-de.com/blog/2019-05-29/7658)
この方法でBViewControllerにtextFieldisBlank()を追加することはできましたが、私の達成したかった”TextFieldが空白である状態を検知し、SearchBarクラスのdelegateを介して、BViewControllerに処理をさせる”ということはできませんでした。
[エラー]
@objc func textFieldDidChange (notification: NSNotification) {
//Value of type 'SearchBarDelegate' has no member 'textFieldisBlank'
delegate?.textFieldisBlank()
}
このような方法では、できないのかも、、、
参考(https://stackoverflow.com/questions/36777600/how-to-set-delegate-in-a-protocol-extension)
設計の段階から見直す必要があるかもしれません。。。
とりあえず、使わないメソッドに関しては空白のままでいきたいと思います。
reeebockさんのご指摘により、共通メソッドを知ることができました。
ご回答ありがとうございました。
?
回答1件
あなたの回答
tips
プレビュー