59401


Webブラウザを作っています。  
読み込み中に画面下に配置したツールバーに表示されるはずのactivityIndicatorが表示されません。おそらくWebViewのdeligateができていないせいだと思いますが…。

Xcode8対応の参考書を元にしているので、UIWebViewでの記述しか載っておらず、WKWebViewでの記述がわかりません。調べてみたものの、解決できませんでした。どなたか知恵をお貸しください。

以下は実行はできるが、Indicatorが表示されないコードです。

[code]

    import UIKit
    import WebKit
    
    class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
    
        @IBOutlet weak var webView: WKWebView!
    
        @IBOutlet weak var searchBar: UISearchBar!
    
        @IBOutlet weak var backButton: UIBarButtonItem!
    
        @IBOutlet weak var reloadButton: UIBarButtonItem!
    
        @IBOutlet weak var stopButton: UIBarButtonItem!
    
        @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
    
        let homeUrlString = "https://google.com"
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            open(urlString: homeUrlString)
        }
    
        func open(urlString: String){
            let url = URL(string: urlString)
            let urlRequest = URLRequest(url: url!)
            webView.load(urlRequest)
        }
    
        //MARK:- UIWebViewDelegate
    
        func webViewDidStartLoad(_ webView: UIWebView){
            activityIndicator.alpha = 1
            activityIndicator.startAnimating()
            backButton.isEnabled = false
            reloadButton.isEnabled = false
            stopButton.isEnabled  = true
        }
    
        func webViewDidFinishLoad(_ webView: UIWebView)
        {
            activityIndicator.alpha = 0
            activityIndicator.stopAnimating()
            backButton.isEnabled = webView.canGoBack
            reloadButton.isEnabled = true
            stopButton.isEnabled  = false
    
        }
        //MARK:- IBAction
    
        @IBAction func backButtonTapped(_ sender: UIBarButtonItem) {
            webView.goBack()
        }
    
        @IBAction func reloadButtonTapped(_ sender: UIBarButtonItem) {
            webView.reload()
        }
    
        @IBAction func stopButtonTapped(_ sender: UIBarButtonItem) {
            webView.stopLoading()
        }
    
    }
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/D0ilv.png)](https://i.stack.imgur.com/D0ilv.png)


CC BY-SA 4.0
2019-10-01T13:01:13.343
59400
2019-10-01T16:47:12.097
2019-10-01T16:47:12.097
3060
36035
question
swift ios xcode
Swiftのdelegateについて


まず最初に…  
**_Xcode8対応の参考書を元にしている_**

正直、変化の早いSwiftや最近のiOSのことを考えると、あまりにも古すぎると言えるでしょう。可能な限り自身が今お使いのXcodeのバージョンに即したもの、さすがにXcode
11は出たばかりですが、せめて、Xcode 10用の参考書(あるいはネット記事)を参考にしてください。

あなたがどのような動機でプログラミングを始められたのかわかりませんが、そのような超古い参考書ですと、iOSプログラミングではなく、「iOSの歴史」「Swift変遷史」の方に多くの時間を取られることになるでしょう。

* * *

さて、本題に戻ると、あなたのコードの問題点は大きく2つあります。

  * `webView`のdelegateを設定しているコードが見つからない
  * `UIWebView`用のdelegateメソッドを定義してあるだけ(それらは当然呼ばれない)で、`WKWebView`用のメソッドを定義していない。

1点目についてはそれほど難しくありません。`UIWebView`用の解説記事にも似たようなコードが示されているはずです。

[code]

        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            webView.uiDelegate = self
            webView.navigationDelegate = self //###
    
            open(urlString: homeUrlString)
        }
    
[/code]

`uiDelegate`については、今のところ不要のようですが、念のため設定しておきましょう。

* * *

2点目についてですが、`UIWebView`用のdelegateメソッドと`WKWebView`用のdelegateメソッドでは、いつでも対応するものが存在するわけではありません。ですが、「ほぼ同じ働きをする」程度でよければ、簡単に置き換えられる場合もあります。

"webViewDidStartLoad wkwebview"あたりのキーワードで検索してみると、私の環境では日本語の解説記事も見つかりました。

とりあえず、[英語版の本家stackoverflowの記事](https://stackoverflow.com/a/37513449/6541007)から拾ってきたのがこちら:

[code]

    webViewDidFinishLoad => didFinishNavigation
    webViewDidStartLoad => didStartProvisionalNavigation
    
[/code]

`didStartProvisionalNavigation`と`didFinishNavigation`と言うのは、どちらも`WKNavigationDelegate`のメソッドを表しています。あなたが示されたコードの`webViewDidStartLoad(_:)`と`webViewDidFinishLoad(_:)`の代わりに以下の2つのメソッドを`ViewController`クラスに追加してみてください。

[code]

        //MARK:- WKNavigationDelegate
    
        func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
            activityIndicator.alpha = 1
            activityIndicator.startAnimating()
            backButton.isEnabled = false
            reloadButton.isEnabled = false
            stopButton.isEnabled  = true
        }
    
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            activityIndicator.alpha = 0
            activityIndicator.stopAnimating()
            backButton.isEnabled = webView.canGoBack
            reloadButton.isEnabled = true
            stopButton.isEnabled  = false
        }
    
[/code]

もしかしたら、storyboardの設定等に問題があれば、うまく表示されないかもしれませんが、少なくともこちらのテスト用プロジェクトでは、このコードでご所望の位置に`UIActivityIndicatorView`が表示されます。(ローディングが完了すると消えるので、ネットの状況が良すぎると見逃してしまいますが。)

お試しの上、何かありましたらコメント等でお知らせください。


CC BY-SA 4.0
2019-10-01T14:14:01.067
59401
2019-10-01T14:14:01.067
13972
59400
answer