ios - WKWebView 预估进度

标签 ios webview uiwebview wkwebview

我正在尝试在我的 WKWebView 中实现 Estimated Progress,但似乎无法弄清楚。你能帮忙吗?

这是我得到的:

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];

我看到这个答案有点意思,但那是一个微调器:UIWebView with Progress Bar

Apple 记录了某种estimatedProgress(我假设它是导航栏正下方的蓝色细条,显示进度,就像在 Safari 中一样)但我一般看不出那会怎样实现:https://developer.apple.com/library/ios/documentation/WebKit/Reference/WKWebView_Ref/#//apple_ref/occ/instp/WKWebView/estimatedProgress

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

更新:这就是我现在拥有的。崩溃是因为我的 Progress View 和 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;

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];
    }
}

更新:使用 CocoaPods 这就是我所拥有的,但它显示了两个 View 而不是一个 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];
}

最佳答案

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

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

The WKWebView class is key-value observing (KVO) compliant for this property.

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

Cocoa 中的 KVO 设计模式非常困惑。查看这篇关于 Key Value Observing 最佳实践的优秀 NSHipster 文章.

这是 WKWebViewestimatedProgress 的 KVO 实现:

从您的 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];

在同一个 UIViewController 中设置您的 observeValueForKeyPath 方法来过滤掉 webViewestimatedProgress 属性。然后,您可以直接访问 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];
    }
}

确保在该 UIViewController 的 dealloc 方法中从 UIViewController 中删除 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];
}

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

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

如果您使用的是 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];
    }
}

关于ios - WKWebView 预估进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26198334/

相关文章:

ios - 无法通过 Swift4 回调协议(protocol)和委托(delegate)

ios - 检查字符串中是否有违禁单词

webview - 检测wxPython的html2-webview中的链接鼠标悬停事件

javascript - 网页无法在 Android 应用内浏览器上正确加载

android - Intent putExtra,NullPointerException

ios - 加载期间 UIWebView 上的黑色区域

ios - WatchKit 调用 webview

iOS 在模拟器上播放音频成功,但在设备上播放失败

android - Cordova 应用程序的 Linkedin 登录

iphone - 使用 uiwebview 创建一个富文本 uitableviewcell