Swift 中的进度条 WebView

Posted

技术标签:

【中文标题】Swift 中的进度条 WebView【英文标题】:Progressbar WebView in Swift 【发布时间】:2015-01-26 08:59:56 【问题描述】:

我正在用 xcode 快速编写一个 webapp。 我有一个问题“如何添加一个进度条来显示每个页面的加载情况?”

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

(对不起我的英语)

【问题讨论】:

【参考方案1】:

您可以找到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
        
    

【讨论】:

感谢您的回答,但我需要它来快速运行,我如何在我的 swift-app 中使用该代码? 嘿,我添加了一些代码。您只需将进度视图添加到您的 UI。 我在哪里添加这些? var theBool: Bool var myTimer: NSTimer 如果我将这些添加到类 ViewController 我得到错误:类 ViewController 没有初始化程序。 这是因为如果将这些添加到类中,它们需要在初始化时进行初始化。 var theBool: Bool = false var myTimer = NSTimer() 另一个选项,而不是定义funcToCallCalledWhenUIWebViewFinishesLoading(),是在控制器中实现UIWebViewDelegate并覆盖webViewDidFinishLoad函数。您还必须将 webview 的委托设置为控制器才能正常工作。【参考方案2】:
    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()
  

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

【讨论】:

这个最准确 @HashemAboonajmi 实际上要走的路是 WKWebKit 或 WKWebView(不记得确切的名称)或 SafariViewController。如果您需要有关进度条的帮助,请给我留言。【参考方案3】:

我正在使用它,看起来不错。

@IBOutlet var webView: UIWebView!
@IBOutlet var progressView: UIProgressView!
override func viewDidLoad() 
   super.viewDidLoad()
   let url = NSURL(string: "http://***.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)

【讨论】:

【参考方案4】:

斯威夫特 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

【讨论】:

【参考方案5】:

为什么不使用

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

【讨论】:

以上是关于Swift 中的进度条 WebView的主要内容,如果未能解决你的问题,请参考以下文章

android进度条怎么显示百分比

进度条和 webview 问题

在 WebView 中添加进度条

如何停止 Android webView swipeToRefresh 加载进度条?

iOS-WebView(WKWebView)进度条

用户体验超棒的微信WebView进度条