WKWebView估计进度

Rea*_*omp 17 uiwebview webview ios wkwebview

我正试图Estimated Progress在我的实施,WKWebView但似乎无法搞清楚.你能帮我吗?

这是我得到的:

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];
Run Code Online (Sandbox Code Playgroud)

我看到这个答案得到了一点,但这对于一个微调器来说:带有进度条的UIWebView

而且Apple的文档是某种形式的estimatedProgress(我假设它的导航栏正下方显示了蓝色条形图,显示了Safari中的进度),但我一般不会看到如何实现它:https://developer.apple.com /库/ IOS /文档/ WebKit的/参考/ WKWebView_Ref /#// apple_ref/OCC/instp/WKWebView/estimatedProgress

所以我被困在这里.任何帮助将不胜感激,谢谢!

更新:这就是我现在所拥有的.因为看起来我的进度视图和WKWebView加载了两次而导致崩溃,我不确定为什么会这样.获得需要删除观察者的错误.这是我的代码,因为它代表 -

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;
Run Code Online (Sandbox Code Playgroud)

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];
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:使用CocoaPods这是我所拥有的,但它显示两个视图而不是一个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];
}
Run Code Online (Sandbox Code Playgroud)

dfm*_*uir 51

检查GitHub上的KINWebBrowser以查看下面解决方案的完整实现.

如果仔细查看链接到的estimatedProgress属性的文档,WKWebView您将看到:

The WKWebView class is key-value observing (KVO) compliant for this property.
Run Code Online (Sandbox Code Playgroud)

这意味着您可以在estimatedProgress属性上设置键值观察,以观察其值的变化.通过该observeValueForKeyPath方法,您可以更新UI.

Cocoa中的KVO设计模式相当混乱.查看这篇关于Key Value Observing最佳实践的优秀NSHipster文章.

以下是estimatedProgresson 的KVO实现WKWebView:

从你的角度出发UIViewController,设置WKWebView并添加自我作为观察者estimatedProgress

    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.webView];

    [self.webView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:NSKeyValueObservingOptionNew context:NULL];
Run Code Online (Sandbox Code Playgroud)

在同一UIViewController设置你的observeValueForKeyPath方法来过滤掉estimatedProgress属性webView.然后,您可以estimatedProgress直接访问该值并相应地更新您的UI.

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.webView) {
        NSLog(@"%f", self.webView.estimatedProgress);
        // estimatedProgress is a value from 0.0 to 1.0
        // Update your UI here accordingly
    }
    else {
        // Make sure to call the superclass's implementation in the else block in case it is also implementing KVO
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}
Run Code Online (Sandbox Code Playgroud)

确保从该UIViewControllerUIViewController的dealloc方法中删除KVO .如果isViewLoaded尚未添加观察者,请务必检查是否要避免崩溃.

- (void)dealloc {

    if ([self isViewLoaded]) {
        [self.wkWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
    }

    // if you have set either WKWebView delegate also set these to nil here
    [self.wkWebView setNavigationDelegate:nil];
    [self.wkWebView setUIDelegate:nil];
}
Run Code Online (Sandbox Code Playgroud)

要在一些大型文件中查看此操作,请加载这个甜蜜星系的巨大图像文件.(此文件为35MB.请确保您使用的是WiFi!)

    NSURLRequest *URLRequest = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.spacetelescope.org/static/archives/images/large/opo0328a.jpg"]];
    [self.webView loadRequest:URLRequest];
Run Code Online (Sandbox Code Playgroud)

如果您正在使用a UIProgressView,则可以使用以下代码实现淡出效果之类的Safari:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.wkWebView) {
        [self.progressView setAlpha:1.0f];
        [self.progressView setProgress:self.wkWebView.estimatedProgress animated:YES];

        if(self.wkWebView.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];
    }
}
Run Code Online (Sandbox Code Playgroud)


Arr*_*ray 27

雨燕样:

@IBOutlet weak var progressView: UIProgressView!

//...

func viewDidLoad() {
    webView.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil) // add observer for key path
}

// ...

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    if (keyPath == "estimatedProgress") { // listen to changes and updated view
        progressView.hidden = webView.estimatedProgress == 1
        progressView.setProgress(Float(webView.estimatedProgress), animated: true)
    }
}
Run Code Online (Sandbox Code Playgroud)

Swift 3更新:

// Add Observer in viewDidLoad
webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)


override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 
{
        if (keyPath == "estimatedProgress") { // listen to changes and updated view
            progress.isHidden = webView.estimatedProgress == 1
            progress.setProgress(Float(webView.estimatedProgress), animated: false)
        }
}


Also please make sure to implement "WKNavigationDelegate" and add webview reference navigationDelegate to self like below

webView.navigationDelegate=self
Run Code Online (Sandbox Code Playgroud)

  • 你错过了这个`deinit {webView.removeObserver(self,forKeyPath:"estimatedProgress")}` (17认同)
  • 对于 Swift 3,我建议使用 keyPath 宏:`#keyPath(WKWebView.estimatedProgress)`,对于 Swift 4,它只是 `\WKWebView.estimatedProgress`。 (2认同)