Swift 中的进度条 WebView

Progressbar WebView in Swift

我正在用 xcode 在 swift 中编写一个网络应用程序。 我有一个问题"How can I add a progressbar that shows me the loading of each page?"

@IBOutlet var webView: UIWebView!
override func viewDidLoad() {
   super.viewDidLoad()
   let url = NSURL(string: "http://whosebug.com")
   let request = NSURLRequest(URL: url)
   webView.loadRequest(request)
}

(对不起我的英语)

您可以找到 a very good answer in this post。您可以将进度条作为子视图添加到您的 web 视图中。主要问题是进度条的准确性。建议的答案是从不断地动画开始,在加载时将其阻止在 95%,当您的请求完成时,将其一直压缩到 100%。

这是 Swift 中的解决方案:

添加这些属性:

//Add this progress view via Interface Builder (IBOutlet) or programatically
let myProgressView: UIProgressView

var theBool: Bool
var myTimer: NSTimer

这些功能将填充进度视图。你可以玩参数:

func funcToCallWhenStartLoadingYourWebview() {
    self.myProgressView.progress = 0.0
    self.theBool = false
    self.myTimer = NSTimer.scheduledTimerWithTimeInterval(0.01667, target: self, selector: "timerCallback", userInfo: nil, repeats: true)
}

func funcToCallCalledWhenUIWebViewFinishesLoading() {
    self.theBool = true
}

func timerCallback() {
    if self.theBool {
        if self.myProgressView.progress >= 1 {
            self.myProgressView.hidden = true
            self.myTimer.invalidate()
        } else {
            self.myProgressView.progress += 0.1
        }
    } else {
        self.myProgressView.progress += 0.05
        if self.myProgressView.progress >= 0.95 {
            self.myProgressView.progress = 0.95
        }
    }
}
    var theBool: Bool
    var myTimer: NSTimer
    var didFinishTimer: NSTimer


    required init(coder aDecoder: NSCoder) {
        self.theBool = false
        self.myTimer = NSTimer()
        self.didFinishTimer = NSTimer()

        super.init(coder: aDecoder)
    }
           func startAnimatingProgressBar() {
            self.theBool = false
            myProgressView.hidden = false
            myProgressView.alpha = 0
            UIView.animateWithDuration(0.2, animations: { () -> Void in
                self.myProgressView.alpha = 0.6
            })
            self.myProgressView.progress = 0.0

            //Tweek this number to alter the main speed of the progress bar
            var number = drand48() / 80;
//            println("startAnimatingProgressBar|\(number)")

            self.myTimer = NSTimer.scheduledTimerWithTimeInterval(number, target: self, selector: "timerCallback", userInfo: nil, repeats: true)
//            println("myTimer|\(myTimer)")
    }

    func finishAnimatingProgressBar() {
        self.theBool = true
    }

    func timerCallback() {
        if self.theBool {
            if self.myProgressView.progress >= 1 {
                UIView.animateWithDuration(0.2, animations: { () -> Void in
                    self.myProgressView.alpha = 0

//                    }, completion: { (success:Bool) -> Void in
//                        self.myProgressView.hidden = true
                })
                self.myTimer.invalidate()
            } else {
                //Loaded and zoom to finish
                var number = drand48() / 40
//                println("finished:\(number)")

                self.myProgressView.progress += Float(number)
            }

        } else {
            //Start slow
            if self.myProgressView.progress >= 0.00 && self.myProgressView.progress <= 0.10 {
                var number = drand48() / 8000;
//                println("Start:\(number)")

                self.myProgressView.progress += Float(number)
                //Middle speed up a bit
            } else if self.myProgressView.progress >= 0.10 && self.myProgressView.progress <= 0.42 {
                var smallerNumber = drand48() / 2000;
                self.myProgressView.progress += Float(smallerNumber)
//                println("Middle:\(smallerNumber)")

                //slow it down again
            } else if myProgressView.progress >= 0.42 && self.myProgressView.progress <= 0.80 {
                var superSmallNumber = drand48() / 8000;
                self.myProgressView.progress += Float(superSmallNumber)
//                println("slow it down:\(superSmallNumber)")

                //Stop it
            } else if myProgressView.progress == 0.80 {
                println("Stop:\(myProgressView.progress)")
                self.myProgressView.progress = 0.80
            }
        }
    }


    var webViewLoads = 0
    var webViewDidStart:Int = 0
    var webViewDidFinish:Int = 0

  func webViewDidStartLoad(webView: UIWebView) {


    webViewDidStart++
    webViewLoads++

    if webViewLoads <= 1 {
        startAnimatingProgressBar()
    }

    println("webViewDidStartNumber: = \(webViewDidStart)")
    println("webViewLoadsStart: = \(webViewLoads)")

//    println("webViewDidStartLoad")

    UIApplication.sharedApplication().networkActivityIndicatorVisible = true
    updateToolbarItems()
  }

  func webViewDidFinishLoad(webView: UIWebView) {

        webViewLoads--
        webViewDidFinish++

        println("webViewDidFinishLoad \(webViewDidFinish)")

    if webViewLoads == 0 {
        finishAnimatingProgressBar()
//        println("webViewLoads \(webViewLoads)")
        return
    }
    getWebsiteInfo()
    UIApplication.sharedApplication().networkActivityIndicatorVisible = false

    updateToolbarItems()

  func webView(webView: UIWebView, didFailLoadWithError error: NSError) {
    theBool = true
    webViewLoads = 0
    UIApplication.sharedApplication().networkActivityIndicatorVisible = false

    println("didFailLoadWithError")

    updateToolbarItems()
  }

我花了很长时间才弄清楚如何确定网站何时已完全加载并根据...为进度条设置动画...经过一些核心谷歌搜索后,这是我能想到的最好的方法。很多人说了很多东西,其中大部分对我没有帮助……添加和改进如果您发现更好的东西,请告诉我。

我正在用这个,看起来不错。

@IBOutlet var webView: UIWebView!
@IBOutlet var progressView: UIProgressView!
override func viewDidLoad() {
   super.viewDidLoad()
   let url = NSURL(string: "http://whosebug.com")
   let request = NSURLRequest(URL: url)
   webView.loadRequest(request)
   webView.delegate=self
}

func webViewDidStartLoad(_ webView: UIWebView) {

    self.progressView.setProgress(0.1, animated: false)
}


func webViewDidFinishLoad(_ webView: UIWebView) {

    self.progressView.setProgress(1.0, animated: true)
}

func webView(_ webView: UIWebView, didFailLoadWithError error: NSError?) {

    self.progressView.setProgress(1.0, animated: true)
}

为什么不用

loadRequest(_ request: URLRequest, progress: ((UInt, Int64, Int64) -> Swift.Void)?, success: ((HTTPURLResponse, String) -> String)?, failure: ((Error) -> Swift.Void)? = nil)

Swift 5

@IBOutlet weak var webView: WKWebView!
@IBOutlet weak var progressView: UIProgressView!

override func viewDidLoad() {
    super.viewDidLoad()

webView.addObserver(self, forKeyPath:
                #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)
}


override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
       if keyPath == "estimatedProgress" {
           print("estimatedProgress")
           progressView.progress = Float(webView.estimatedProgress)
       }
   }

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