I'm trying to implement Estimated Progress
in my WKWebView
but can't seem to figure it out. Can you help?
Here's what I've got:
self.view = self.webView;
NSURL *url = [NSURL URLWithString:stringWeb];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
[self.webView loadRequest:request];
I see this answer gets at it a bit, but thats for a spinner: UIWebView with Progress Bar
And Apple documents some sort of estimatedProgress
(I'm assuming its the thin blue bar right below the navigation bar that shows progress like in Safari) but I don't see generally how that would be implemented: https://developer.apple.com/library/ios/documentation/WebKit/Reference/WKWebView_Ref/#//apple_ref/occ/instp/WKWebView/estimatedProgress
So I'm stuck here. Any help would be appreciated, thanks!
UPDATE: This is what I have right now. Getting a crash because it looks like my Progress View and WKWebView are loading twice, and I'm not sure why that would be. Getting an error that observer needs to be removed. Here's my code as it stands-
ViewController.h
@interface WebPageViewController : UIViewController <UIWebViewDelegate>
@property (strong, nonatomic) NSString *stringMobile;
@property (strong, nonatomic) NSString *stringWeb;
@property (strong, nonatomic) IBOutlet UIView *view;
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic) UIProgressView *progressView;
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.webView];
[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:NULL];
self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
self.progressView.center = self.view.center;
[self.view addSubview:self.progressView];
NSURLRequest *URLRequest = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:stringWeb]];
[self.webView loadRequest:URLRequest];
}
- (void)dealloc {
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
// if you have set either WKWebView delegate also set these to nil here
[self.webView setNavigationDelegate:nil];
[self.webView setUIDelegate:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"estimatedProgress"] && object == self.webView) {
[self.progressView setAlpha:1.0f];
[self.progressView setProgress:self.webView.estimatedProgress animated:YES];
if(self.webView.estimatedProgress >= 1.0f) {
[UIView animateWithDuration:0.3 delay:0.3 options:UIViewAnimationOptionCurveEaseOut animations:^{
[self.progressView setAlpha:0.0f];
} completion:^(BOOL finished) {
[self.progressView setProgress:0.0f animated:NO];
}];
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
UPDATE: Using the CocoaPods this is what I have but its showing two Views instead of just one webview
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *myURL = [NSURL URLWithString: [self.url stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding]];
NSURLRequest *request = [NSURLRequest requestWithURL:myURL];
//[self.webView loadRequest:request];
// KIN
// Deleted UIWebView in Storyboard
KINWebBrowserViewController *webBrowser = [[KINWebBrowserViewController alloc] init];
[self.navigationController pushViewController:webBrowser animated:YES];
[webBrowser loadURL:myURL];
}
Best Answer
Check KINWebBrowser on GitHub to see a full implementation of the solution below.
If you look closely at the documentation for the
estimatedProgress
property ofWKWebView
that you linked to you will see:This means that you can set up key value observing on the
estimatedProgress
property to observe changes to it's value. From theobserveValueForKeyPath
method you can update your UI.The KVO design pattern in Cocoa is pretty messy. Check out this excellent NSHipster article about the best practices of Key Value Observing.
Here is the KVO implementation for
estimatedProgress
onWKWebView
:From your
UIViewController
, set up yourWKWebView
and add self as an observer ofestimatedProgress
In the same
UIViewController
set up yourobserveValueForKeyPath
method to filter out theestimatedProgress
property ofwebView
. You can then access theestimatedProgress
value directly and update your UI accordingly.Make sure to remove KVO from the
UIViewController
in the dealloc method of that UIViewController. It is important to check ifisViewLoaded
to avoid a crash if the observer has not already been added.To see this in action on some large files load a huge image file of this sweet galaxy. (This file is 35MB. Make sure you are on WiFi!)
If you are using a
UIProgressView
you can achieve a safari like fade-out effect with this code: