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

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

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

(对不起我的英语)

【问题讨论】:

    标签: ios xcode swift webview uiwebview


    【解决方案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://stackoverflow.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)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-26
          • 1970-01-01
          • 2011-02-02
          • 1970-01-01
          • 1970-01-01
          • 2011-05-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多