2014-01-21 52 views
21

嗨,我是新的编程,我试图让我的第一个应用程序上的Xcode的iPhone。 我的应用程序包含一个按钮,它在按下时打开一个UIWebView并加载一个主页。 现在我也想要像Safari那样将一个Progress View添加到WebView中,它表示加载页面的进度。我怎样才能做到这一点?
到目前为止我的代码在UIWebView中加载的网址:UIWebView的使用进度条

.H

IBOutlet UIWebView *webView; 

.M

- (void)viewDidLoad 
{ 
[webView loadRequest:[NSURLRequest requestWithURL: [NSURL URLWithString:@"http:/www.google.com/"]]]; 

感谢您的帮助!

+0

查看这里的答案,以获得更好的解决方案,了解放置进度条代码的位置http://stackoverflow.com/questions/23966697/show-progress-bar-until-it-load-the-data -in-uiwebview-ios7 – Suhaib

回答

67

有一个准确的UIProgressView,你需要有一些任务:

  • 您可以从获取信息,而这是不完整的
  • 量化它的“完整性”基于这些信息的百分比。

现在当你加载你的UIWebView,那是不可能的。而苹果也没有这样做。在加载页面时,Apple经常使用假冒UIProgressViews给你一些东西。邮件也使用虚假的进度视图。去自己尝试一下。这就是苹果的假进度的看法工作:

  • 的发展观开始以缓慢,恒定速率
  • 移动如果条完成前的任务完成后,它突然越过其余拉链100%消失
  • 如果任务需要很长时间,则进度视图将停止在95%,并且会一直保持到任务完成。

要做到这一点,你必须手动动画progressView。你可以对它进行子类化,但这可能会对你有所帮助。最简单的方法是这样的:

在myViewController.h

@interface myViewController : UIViewController { 
    BOOL theBool; 
    //IBOutlet means you can place the progressView in Interface Builder and connect it to your code 
    IBOutlet UIProgressView* myProgressView; 
    NSTimer *myTimer; 
} 
@end 

在myViewController.m

#import "myViewController.h" 
@implementation myViewController 
- (void)webViewDidStartLoad:(UIWebView *)webView{ 
    myProgressView.progress = 0; 
    theBool = false; 
    //0.01667 is roughly 1/60, so it will update at 60 FPS 
    myTimer = [NSTimer scheduledTimerWithTimeInterval:0.01667 target:self selector:@selector(timerCallback) userInfo:nil repeats:YES]; 
} 
- (void)webViewDidFinishLoad:(UIWebView *)webView{ 
    theBool = true; 
} 
-(void)timerCallback { 
    if (theBool) { 
     if (myProgressView.progress >= 1) { 
       myProgressView.hidden = true; 
       [myTimer invalidate]; 
     } 
     else { 
       myProgressView.progress += 0.1; 
     } 
    } 
    else { 
     myProgressView.progress += 0.05; 
     if (myProgressView.progress >= 0.95) { 
       myProgressView.progress = 0.95; 
     } 
    } 
} 
@end 

然后,在你的任务完成后得到,设置theBool = true;和进度视图会照顾本身。更改if语句中的值以控制动画的速度。

+2

_ + 1_在提交我之前没有正确地阅读你的答案,这也提示假进度条:) – Tricertops

+0

谢谢你的帮助。但它不适用于我。我究竟做错了什么?我在我的Web视图中放入了一个Progress View,并将它与'IBOutlet'连接起来。现在我可以在运行模拟器的同时看到进度视图,但不会生成动画。 – user3220034

+0

当我把例如0,5在进度视图的属性检查器中的进度字段中,进度视图将从0.5开始,然后在没有动画的情况下突然跳到0。 – user3220034

0

我会添加注释,而不是增加一个答案,但我还没有足够的信誉发表评论!

只有前两天,我问几乎一模一样的问题。在那个问题中,我包含了我提出的解决方案。我的解决方案比WolfLink更复杂,但它确实可以跟踪加载页面的真实进度,尽管它不是100%准确的。正如WolfLink所说,这是不可能的。我的问题可以在这里找到:Progress bar for UIWebView

注意无论你这样做,你需要检查UIWebView的加载属性,以确定何时加载的页面完成。

+0

谢谢。我绝对不期待它会如此复杂:p – user3220034

2

这是困难的(如果甚至有可能),因为你必须跟踪由网站加载的所有资源,但...

我有一个想法。它更像是一个不能真正解决问题,但我认为,即使苹果在消息应用程序:)

  1. 当您启动加载页面,开始一个动画到90%的进度使用这个(让我们比如1.5秒的持续时间,对于Wi-Fi,LTE,3G ......也许是不同的)。
  2. 当页面加载在此期间,快速动画进度为100%。完成!
  3. 如果页面需要更多的时间来加载,进度条将停止在90%以上,并在那里等候。用户在状态栏中观看慢速旋转指示器时的沮丧时刻!最后,页面完成加载和(如第2项),您将快速动画播放到100%。完成!

我想大家都知道,这是消息应用程序是如何工作的,因为我不相信发送短信可以用这样的准确进度:)

3

我跟着Wolflink的答案,并发现了同样的问题被跟踪没有progressView动画。

阅读的NSTimer类参考后:

https://developer.apple.com/library/Mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html#//apple_ref/occ/clm/NSTimer/timerWithTimeInterval:target:selector:userInfo:repeats

讨论你可以阅读: “你必须将新的计时器添加到运行循环,使用addTimer:forMode:”。

所以我加了

[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];

myTimer = [NSTimer timerWithTimeInterval:0.01667 target:self selector:@selector(timerCallback) userInfo:nil repeats:YES];

它为我(作为WolfLink建议我做了子类UIProgressView)

+0

感谢您的注意!我打算使用'[NSTimer scheduledtimerWithTimeInterval:0.01667 target:self selector:@selector(timerCallback)userInfo:nil repeats:YES];'这会将定时器自动添加到运行循环中。 – WolfLink

+0

即使更干净,我会用那种方式。我已经看到你已经编辑了你的答案,所以@ user3220034可以将它标记为正确的答案。至少这是我在找的东西。 – danihvilla

4

雨燕2.2

class ViewController: UIViewController,UIWebViewDelegate { 

    @IBOutlet weak var webView: UIWebView! 
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView! 
    @IBOutlet weak var myProgressView: UIProgressView! 

    var myTimer = NSTimer() 
    var theBool = Bool() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let url = NSURL(string: "https://www.youtube.com") 
     let request = NSURLRequest(URL: url!) 
     activityIndicator.hidesWhenStopped = true 
     activityIndicator.startAnimating() 
     webView.loadRequest(request) 

    } 
    func timerCallback(){ 
     if theBool { 
      if myProgressView.progress >= 1 { 
       myProgressView.hidden = true 
       myTimer.invalidate() 
      }else{ 
       myProgressView.progress += 0.1 
      } 
     }else{ 
      myProgressView.progress += 0.05 
      if myProgressView.progress >= 0.95 { 
       myProgressView.progress = 0.95 
      } 
     } 
    } 

    func webViewDidStartLoad(webView: UIWebView) { 
     activityIndicator.startAnimating() 
     myProgressView.progress = 0 
     theBool = false 
     myTimer = NSTimer.scheduledTimerWithTimeInterval(0.01667,target: self,selector: #selector(ViewController.timerCallback),userInfo: nil,repeats: true) 
    } 
    func webViewDidFinishLoad(webView: UIWebView) { 
     activityIndicator.stopAnimating() 
     theBool = true 
    } 
} 
2

如果有人想这样做在迅速3,我花了几天的时间试图弄清楚,最终做到了。

下面是代码:)

override func viewDidLoad() { 
    super.viewDidLoad() 

    let url = NSURL(string: "http://google.com") 
    let request = NSURLRequest(url: url as! URL) 
    webView.loadRequest(request as URLRequest) 
    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: Error) { 

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

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 
0

苹果现在提供WebKit的框架,其中包括WKWebView类,它允许您使用属性“estimatedProgress”查询估算进度,让您不再必须“假冒“你在UIWebView上显示进度条的进展。