为什么无法在 Swift 上的 Webview 中显示指标?

Why can not show indicator in Webview on Swift?

我是 iOS 开发的初学者。现在,当我按下一个按钮时,我在一个显示 webView 的页面上。我在加载时标记了 indicator。我看不到它。我把它标记为在加载时可见,但是有什么问题?

故事板

ButtonEvent

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

WebView 控制器

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
            }
        }
    }
    
}

我把网线拿出来试了一下,看不到。

此外,我想将指标用作 png 文件。我有大量的 png 文件。如何使用指标动画?

提前致谢

*************************** 编辑开始 **************** **************

看到答案后试了试,但是报错


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 开始 **************** **************

//
//  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()
        }
    }
    
}

我可以看到两个错误 Cannot assign value of type 'UsageDetail' to type 'WKNavigationDelegate?'Declaration is only valid at file scope *************************** 编辑结束 ********************* *********

添加观察者也不是一个坏方法,但我认为最简单的方法是符合 WKNavigationDelegate 并且在创建 URL 时尽量避免强制展开(如果你有一些空间或坏字符这会使您的应用程序崩溃。因此请始终尝试使您成为可选链接)就像我在下面提到的那样

正在 viewDidLoad 中调用 loadWebPage。

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()
    }
}

尝试将代码放在 'observeValue' 调度异步中:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "loading" {
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            if self.UsageWebView.isLoading {
                self.usageIndicator.startAnimating()
                self.usageIndicator.isHidden = false
            } else {
                self.usageIndicator.stopAnimating()
                self.usageIndicator.isHidden = true
            }
        }
    }
}