iOS UIWebview仿微信進度條

躍然發表於2016-01-27

一、實現:
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)viewDidLoad {
    [super viewDidLoad];

    // 仿微信進度條
    CGFloat progressBarHeight = 2.f;
    CGRect navigationBarBounds = self.navigationController.navigationBar.bounds;
    CGRect barFrame = CGRectMake(0, navigationBarBounds.size.height - progressBarHeight, navigationBarBounds.size.width, progressBarHeight);
    myProgressView = [[UIProgressView alloc] initWithFrame:barFrame];
    myProgressView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
    myProgressView.progressTintColor = [UIColor colorWithRed:43.0/255.0 green:186.0/255.0  blue:0.0/255.0  alpha:1.0];
    [self.navigationController.navigationBar addSubview:myProgressView];

    // 設定網路請求失敗情況頁面顯示   
    [self loadFailViewSetting];
    // 請求網路
    [self reRequesrtUrl];
}

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];

    // 移除 progress view
    // because UINavigationBar is shared with other ViewControllers
    [myProgressView removeFromSuperview];  
}

- (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

二、原理:

It's difficult (if even possible), since you would have to track all resources loaded by the site, but …
I have one idea. It's more of a **trick** than a real solution, but I think even Apple uses this in Messages app :)

1. When you start loading the page, **begin an animation to 90%** of the progress (let's say with duration of 1.5 seconds, maybe be different for Wi-Fi, LTE, 3G, …).
2. When page loads in meantime, **quickly animate the progress to 100%**. Done!
3. If the page takes more time to load, the progress bar **will stop at 90% and will wait there**. Frustrating moment when the user watches slow spinning indicator in status bar! And then finally, the page finish loading and (as in bullet 2.) you play **quick animation to 100%**. Done!

I think we all know, that this is how Messages app works, since I don't believe sending SMS can be tracked with such accurate progress :)

大致意思,就是這個進度條是個假象,先進度到90%,然後等待載入完畢,完畢後瞬間進度到100%。

仿微信進度條,暫時是這樣處理的。如您有更好的方法,歡迎給予指點。

相關文章