Delegateメソッドの使い方に関しまして、自分の理解が正しいかどうか分からなかった為、ご質問させて頂きました。
以下のコードにおきまして、画面がロードが開始した際に使われるメソッド func webView〜didcommit
及びfunc webView〜didfinish
は デリゲートメソッドであるかと思います。このデリゲートメソッドなのですが、基本的には、使用する際class ViewController: UIViewController,WKNavigationDelegate
このようにし、継承するクラスのような記述をするかと思います。自分の理解では、クラスとの違いにつきましては、必ず使用するメソッドはオーバーライドしなければならず、webView.navigationDelegate = self
このようにデリゲートプロパティをもつ、インスタンスに対し、どこのクラスで処理を行うかを指定しなければならない(今回の場合はselfを指定している為、ViewController内で、func webView
の処理を行わなければならない)このように理解しているのですが、合っていますでしょうか...?
もし、理解に間違いなどありましたら、教えていただけましたら幸いです。
よろしくお願いします。
import UIKit
import WebKit
class ViewController: UIViewController,WKNavigationDelegate {
var webView = WKWebView()
@IBOutlet weak var indicator: UIActivityIndicatorView!
@IBOutlet weak var toolBar: UIToolbar!
override func viewDidLoad() {
super.viewDidLoad()
//実体になっているか
//大きさ
webView.frame = CGRect(x: 0, y: toolBar.frame.size.height, width: view.frame.size.width, height: view.frame.size.height - toolBar.frame.size.height*2)
view.addSubview(webView)
//何をロードするか
webView.navigationDelegate = self
let url = URL(string: "https://www.yahoo.co.jp/")
let request = URLRequest(url:url!)
webView.load(request)
//ロードが開始された時
func webView(_ webview:WKWebView, didCommit: WKNavigation){
print("読み込み開始")
indicator.startAnimating()
}
//ロードが完了した時
func webView(_webView: WKWebView, didFinish navigation: WKNavigation!){
print("ロード完了")
indicator.stopAnimating()
}
//どこにつけるか
}
@IBAction func go(_ sender: Any) {
}
@IBAction func back(_ sender: Any) {
webView.goBack()
}
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
WKNavigationDelegate
はクラスではなくて、プロトコルです。従って、class ViewController: UIViewController,WKNavigationDelegate
という文は、「ViewController
は、UIViewController
クラスを継承し、WKNavigationDelegate
プロトコルを適用したクラスである」と宣言しています。
親クラスとプロトコルを並べて書きますが、実際には意味が違っています。(なお、プロトコルより先に親クラスを書かないとエラーになります)
クラスの継承については、ご理解のとおりです。
webView.navigationDelegate = self
という文は、webView
にself
を呼んでくれと頼んでいます。
これは、webView
に対して、self
がWKWebViewDelegate
プロトコルに準拠したオブジェクトである事を伝えています。webView.navigationDelegate
の型が、WKNavigationDelegate
プロトコルなので、self
を代入できる事でコンパイル時にそのことが保証されます。
これによって、webView
は、self
が実装している、WKNavigationDelegate
プロトコルのメソッド類を呼び出すようになります。
ということは、WKNavigationDelegate
プロトコルは、webView
がどのようにself
を呼ぶかを規程したインターフェースだという事です。
プロトコルには、必須のメソッドと、そうでないメソッドを定義できます。必須のものは、提供しなければビルドできません。必須でないものは提供しなくてもかまいません。
デリゲートの場合は、必須でないメソッドが多いので、必要なものだけつまみ食いして作ることができて、便利です。
デリゲーション(移譲)は、デザインパターンです。オブジェクト指向における技みたいなもので、責任の移譲などといいますが、要は、実際の処理(責任)を、未来に実装されるものに任せる(移譲する)仕組みです。将来実装してもらうために、インターフェースだけをWKWebViewDelegate
プロトコルとして定義しておいて、それを使うように、WKWebView
を作ってあります。そのようにして、個々のユーザーがあとからWKWebView
の動作をカスタマイズできるようにしています。
なお、Swiftでは、プロトコルは、クラス、構造体、列挙型に適用できます。
余談ですが、WKNavigationDelegate
のメソッドを定義するとき、override
をつけないのは、クラスではなくインターフェースだから、だと思っています。
元々、「インターフェース」は、実装ぬきで型のみを抜き出した概念でした。クラスへのインターフェースの適用は、型だけしかない所に中身である実装を与えるものであって、既存の実装を上書きするのとは異なります。
しかし、実際には、Swiftのプロトコルはプロトコルエクステンションでデフォルト実装を持たせられる、変わったインターフェースです。デフォルト実装がある場合、個々のクラスの実装でそれを「置き換える」ので、override
しているようなものと解釈できるようにも思います。Swift.orgをみてみたら、overrideをつけたいとう要望が時々出ては、一部が強く反対して実現していないようでした。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
とりあえず
//ロードが開始された時
func webView(_ webview:WKWebView, didCommit: WKNavigation){
などのいくつかの関数がviewDidLoad()関数の中に書かれている気がしますが、これだと動かないと思いますので、
viewDidLoad()の外で実装してください。
このように理解しているのですが、合っていますでしょうか...?
たぶん理解は合っていると思います。
デリゲートはあくまで実装方法の名称のようなものであって、Swift的には「プロトコル」という機構を使って実現しています。
そして
必ず使用するメソッドはオーバーライド
プロトコルに書かれた関数を実装することを「オーバーライド」とは、たぶん呼ばないのではないかと思います。
(overrideキーワードも付けませんしね)
※自信ないです
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.18%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2019/11/21 10:15
デリゲートに関しては、理解が難しく前回も質問させて頂いたのですが、詳しくご説明頂き助かりました。
大分理解が出来ましたので、また、分からなくなった際は頂いたご回答を見返させて貰うなどし、引きづつき勉強を続けていきたいと思います。