iosswiftwebviewviewpagerindicator

Why can not show indicator in Webview on Swift?


I am a beginner in iOS development. Now I'm on a page that shows a webView when I press a button. I'm marking the indicator when I'm loading it. I can't see it. I marked it to be visible when loading, but what's the problem?

storyboard

storyboard

ButtonEvent

    @IBAction func DetailFuc(_ sender: Any) {
    }

WebView Controller

import Foundation
import UIKit
import WebKit

let globalUrl = Global()

class UsageDetail: UIViewController {
    
    @IBOutlet weak var UsageWebView: WKWebView!
    @IBOutlet weak var usageIndicator: UIActivityIndicatorView!
    
    func loadWebPage() {
        let detailUrl = globalUrl.getAgreeURL()
        let myUrl = URL(string: detailUrl)
        let myRequest = URLRequest(url: myUrl!)
        UsageWebView.load(myRequest)
        
        UsageWebView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: .new, context: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loadWebPage()
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "loading" {
            if UsageWebView.isLoading {
                usageIndicator.startAnimating()
                usageIndicator.isHidden = false
            } else {
                usageIndicator.stopAnimating()
                usageIndicator.isHidden = true
            }
        }
    }
    
}

I took out the Internet line and tried it, but I couldn't see it.

In addition, I would like to use the indicator as a png file. I have a large number of png files. How can I use an animation of an indicator with it?

Thanks in advance

*************************** Edit start ******************************

I tried it after I saw the answer but there was an error.


import Foundation
import UIKit
import WebKit

let globalUrl = Global()

class UsageDetail: UIViewController {
    
    @IBOutlet weak var UsageWebView: WKWebView!
    @IBOutlet weak var usageIndicator: UIActivityIndicatorView!
    
    func loadWebPage() {
        let detailUrl = globalUrl.getAgreeURL()
        let myUrl = URL(string: detailUrl)
        let myRequest = URLRequest(url: myUrl!)
        UsageWebView.load(myRequest)
        
        UsageWebView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: .new, context: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loadWebPage()
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "loading" {
            if UsageWebView.isLoading {
                usageIndicator.startAnimating()
                usageIndicator.isHidden = false
            } else {
                usageIndicator.stopAnimating()
                usageIndicator.isHidden = true
            }
        }
    }
    
    extension UsageDetail : WKNavigationDelegate { // get error 'Declaration is only valid at file scope'
        func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
            usageIndicator.startAnimating()
        }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        usageIndicator.stopAnimating()
    }
    
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        usageIndicator.stopAnimating()
    }
}
    
}

*************************** EditTWO start ******************************

//
//  UsageDetail.swift
//  dadadac
//
//  Created by taehong on 06/09/2019.
//  Copyright © 2019 Smart Core. All rights reserved.
//

import Foundation
import UIKit
import WebKit

let globalUrl = Global()

class UsageDetail: UIViewController {
    
    @IBOutlet weak var UsageWebView: WKWebView!
    @IBOutlet weak var usageIndicator: UIActivityIndicatorView!
    
    //MARK: View controller lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        loadWebPage()
    }
    
    //MARK: initialise webView
    func loadWebPage() {
        let detailUrl = "globalUrl.getAgreeURL()"
        guard let myUrl = URL(string: detailUrl) else {
            //report invalid URL
            return
        }
        let myRequest = URLRequest(url: myUrl)
        UsageWebView.navigationDelegate = self //Cannot assign value of type 'UsageDetail' to type 'WKNavigationDelegate?'
        UsageWebView.load(myRequest)
    }
    
    
    extension UsageDetail : WKNavigationDelegate {  // Declaration is only valid at file scope
        func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
            usageIndicator.startAnimating()
        }
        
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            usageIndicator.stopAnimating()
        }
        
        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
            usageIndicator.stopAnimating()
        }
    }
    
}

I can see Two Error Cannot assign value of type 'UsageDetail' to type 'WKNavigationDelegate?' And Declaration is only valid at file scope *************************** EditTWO end ******************************


Solution

  • Adding observer is also not a bad approach but I think easiest way will be to conforms the WKNavigationDelegate and also try to avoid force unwrapping when creating URL (if you have some spaces or bad characters this will crash your app. So always try to make you of optional chaining) like I mentioned below

    Calling loadWebPage in viewDidLoad.

    import Foundation
    import UIKit
    import WebKit
    
    let globalUrl = Global()
    
    class UsageDetail: UIViewController {
    
        @IBOutlet weak var UsageWebView: WKWebView!
        @IBOutlet weak var usageIndicator: UIActivityIndicatorView!
    
        //MARK: View controller lifecycle
        override func viewDidLoad() {
            super.viewDidLoad()
            loadWebPage()
        }
    
        //MARK: initialise webView
        private func loadWebPage() {
            let detailUrl = "globalUrl.getAgreeURL()"
            guard let myUrl = URL(string: detailUrl) else {
                //report invalid URL
                return
            }
            let myRequest = URLRequest(url: myUrl)
            UsageWebView.navigationDelegate = self
            UsageWebView.load(myRequest)
        }
    }
    
    extension UsageDetail : WKNavigationDelegate {
        func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
            usageIndicator.startAnimating()
        }
    
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            usageIndicator.stopAnimating()
        }
    
        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
            usageIndicator.stopAnimating()
        }
    }