ios 如何将活动指示器添加到 WKWebView (Swift 3)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40819656/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 10:51:25  来源:igfitidea点击:

How to add Activity Indicator to WKWebView (Swift 3)

iosswift3wkwebviewuiactivityindicatorview

提问by iFunnyVlogger

I have a wkwebview in my app, and I want to add an activity indicator to it. I want it to where it appears when the webview is loading and disappears whenever it is finished loading, it disappears. Can you give me some code to do this? Here's my code right now:

我的应用程序中有一个 wkwebview,我想向它添加一个活动指示器。我希望它在 webview 加载时出现在它的位置,并在加载完成时消失,它消失了。你能给我一些代码来做到这一点吗?这是我现在的代码:

@IBOutlet weak var Activity: UIActivityIndicatorView!
var webView : WKWebView!


@IBOutlet var containerView: UIView? = nil


override func viewDidLoad() {
    super.viewDidLoad()

    guard let url = URL(string: "http://ifunnyvlogger.wixsite.com/ifunnyvlogger/app-twitter") else { return }

    webView = WKWebView(frame: self.view.frame)
    webView.translatesAutoresizingMaskIntoConstraints = false
    webView.isUserInteractionEnabled = true
    webView.navigationDelegate = self

    self.view.addSubview(self.webView)

    let request = URLRequest(url: url)
    webView.load(request)

}


func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

    // Check if a link was clicked
    if navigationAction.navigationType == .linkActivated {

        // Verify the url
        guard let url = navigationAction.request.url else { return }
        let shared = UIApplication.shared

        // Check if opening in Safari is allowd
        if shared.canOpenURL(url) {

            // Ask the user if they would like to open link in Safari
            let alert = UIAlertController(title: "Do you want to open Safari?", message: nil, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (alert: UIAlertAction) -> Void in
                // User wants to open in Safari
                shared.open(url, options: [:], completionHandler: nil)
            }))
            alert.addAction(UIAlertAction(title: "Opps, no.", style: .cancel, handler: nil))

            present(alert, animated: true, completion: nil)

        }
        decisionHandler(.cancel)
    }
    decisionHandler(.allow)
}

func webViewDidStartLoad(_ : WKWebView) {
    Activity.startAnimating()
}

func webViewDidFinishLoad(_ : WKWebView) {
    Activity.startAnimating()
}

I'm creating an IOS app using xcode 8 and swift 3

我正在使用 xcode 8 和 swift 3 创建一个 IOS 应用程序

回答by Sandy

Please, below code which is working fine.

请,下面的代码工作正常。

@IBOutlet weak var Activity: UIActivityIndicatorView!
var webView : WKWebView!
@IBOutlet var containerView: UIView? = nil

override func viewDidLoad() {
    super.viewDidLoad()

    guard let url = URL(string: "http://www.facebook.com") else { return }
    webView = WKWebView(frame: self.view.frame)
    webView.translatesAutoresizingMaskIntoConstraints = false
    webView.isUserInteractionEnabled = true
    webView.navigationDelegate = self
    self.view.addSubview(self.webView)
    let request = URLRequest(url: url)
    webView.load(request)

    // add activity
    self.webView.addSubview(self.Activity)
    self.Activity.startAnimating()
    self.webView.navigationDelegate = self
    self.Activity.hidesWhenStopped = true

}

Implement below these two delegate method:

下面实现这两个委托方法:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    Activity.stopAnimating()
}

func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    Activity.stopAnimating()
}

Let me know if it is not working.

如果它不起作用,请告诉我。

回答by Ian Pinto

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

    var webView: WKWebView!
    var activityIndicator: UIActivityIndicatorView!

    override func viewDidLoad() {
        webView = WKWebView(frame: CGRect.zero)
        webView.navigationDelegate = self
        webView.uiDelegate = self

        view.addSubview(webView)

        activityIndicator = UIActivityIndicatorView()
        activityIndicator.center = self.view.center
        activityIndicator.hidesWhenStopped = true
        activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray

        view.addSubview(activityIndicator)

        webView.load(URLRequest(url: URL(string: "http://google.com")!))
    }

    func showActivityIndicator(show: Bool) {
        if show {
            activityIndicator.startAnimating()
        } else {
            activityIndicator.stopAnimating()
        }
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        showActivityIndicator(show: false)
    }

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        showActivityIndicator(show: true)
    }

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        showActivityIndicator(show: false)
    }
}

回答by Alex Blair

In viewDidLoadyou need to add the activityIndicatoras a subViewjust as you did for your webView. Since it's an outlet, make sure the activityIndicatorsits on top of your webViewand you should be good to go. You also want to set activity.hiddento truewhen the webViewstopsloading.

viewDidLoad您需要添加activityIndicatoras asubView就像您为您的webView. 由于它是一个插座,请确保它activityIndicator位于您的顶部,您webView应该很高兴。您还想设置activity.hidden为何truewebView停止加载。

It's also a good rule of thumb to lower case your 'Activity' outlet.

小写您的“活动”插座也是一个很好的经验法则。

override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.Activity)

guard let url = URL(string: "http://ifunnyvlogger.wixsite.com/ifunnyvlogger/app-twitter") else { return }

webView = WKWebView(frame: self.view.frame)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.isUserInteractionEnabled = true
webView.navigationDelegate = self

self.view.addSubview(self.webView)


let request = URLRequest(url: url)
webView.load(request)

You also call activity.startAnimatingin webViewDidFinishLoad(). Make sure you call activity.stopAnimating()when the webViewfinishes loading. Happy coding!

你也打activity.startAnimating进来webViewDidFinishLoad()。确保activity.stopAnimating()webView完成加载时调用。快乐编码!

    func webViewDidFinishLoad(_ : WKWebView) {
    Activity.stopAnimating()
    Activity.hidden = true
}

回答by yeyo

Swift 5 Version

斯威夫特 5 版本

The concept is simple enough to be ported to earlier swift versions.

这个概念很简单,可以移植到早期的 swift 版本。

This is a class we would use as a parent class anywhere we want a webview.

这是一个我们将在任何需要 webview 的地方用作父类的类。

import UIKit
import WebKit

class CustomWebViewController: UIViewController, WKNavigationDelegate {
    var activityIndicator: UIActivityIndicatorView!

    override func viewDidLoad() {
        super.viewDidLoad()

        activityIndicator = UIActivityIndicatorView()
        activityIndicator.center = self.view.center
        activityIndicator.hidesWhenStopped = true
        activityIndicator.style = .gray
        activityIndicator.isHidden = true

        view.addSubview(activityIndicator)
    }

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        activityIndicator.isHidden = false
        activityIndicator.startAnimating()
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        activityIndicator.stopAnimating()
        activityIndicator.isHidden = true
    }
}

If we have a UIViewController with a webview, we can just inherit from CustomWebViewController and it will take care of the rest for us. Remember to connect the webview IBOutlet.

如果我们有一个带有 webview 的 UIViewController,我们可以从 CustomWebViewController 继承,它会为我们处理其余的事情。记得连接webview IBOutlet。

import UIKit
import WebKit

class FirstViewController: CustomWebViewController {

    @IBOutlet var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.navigationDelegate = self

        let url = URL(string: "https://google.com")
        webView.load(URLRequest(url: url!))
    }
}

回答by Feyzili Mikay?l

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

var webView: WKWebView!
var activityIndicator: UIActivityIndicatorView!

override func viewDidLoad() {
    webView = WKWebView(frame: CGRect.zero)
    webView.navigationDelegate = self;
    webView.uiDelegate = self


    activityIndicator = UIActivityIndicatorView()
    activityIndicator.hidesWhenStopped = true
    activityIndicator.center = self.view.center
    activityIndicator.style = UIActivityIndicatorView.Style.large

    webView.addSubview(activityIndicator)
    view = webView

    let load_url = URL(string: "https://google.com/")!
    webView.load(URLRequest(url: load_url))
    activityIndicator.startAnimating()

    let refresh = UIBarButtonItem(barButtonSystemItem: .refresh, target: webView, action: #selector(webView.reload))
    toolbarItems = [refresh]
    navigationController?.isToolbarHidden = false
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    title = webView.title
    activityIndicator.stopAnimating()
}

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    activityIndicator.startAnimating()
}

func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    activityIndicator.stopAnimating()
}
}

回答by Elamurugan

Please try the below code its working fine for me and please let me know if anything is wrong in it thanks in advance.

请尝试下面的代码,它对我来说工作正常,如果有任何问题,请提前告诉我,谢谢。

import UIKit
import WebKit

class WebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

@IBOutlet weak var contentView: UIView!
@IBOutlet weak var activityIndicatorView: UIActivityIndicatorView!

override func viewDidLoad() {
    super.viewDidLoad()

    setupView()
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    self.setupWebView()
    self.loadData()
}

fileprivate func setupView() {

    self.contentView.isHidden = true
    self.activityIndicatorView.startAnimating()
}

fileprivate func setupWebView() {

    let webConfiguration = WKWebViewConfiguration()

    webView = WKWebView(frame: contentView.bounds, configuration: webConfiguration)
    webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    self.contentView.addSubview(webView)
    self.webView.allowsBackForwardNavigationGestures = true
    webView.uiDelegate = self
    webView.navigationDelegate = self
}

fileprivate func loadData() {

    if let url = URL(string: "http://google.com) {

        /// For loading PDF content 
        if contentType == .pdf {

              if let data = try? Data(contentsOf: url) {
                   self.webView.load(data, mimeType: "application/pdf", characterEncodingName: "", baseURL: url)
              }
        } else {

           let request = URLRequest(url: url)
           webView.load(request)
        }  
   }
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

    activityIndicatorView.stopAnimating()
    self.contentView.isHidden = false
}

func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    activityIndicatorView.stopAnimating()
}
}