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
}
我正在用 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
}