20

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

私はこの答えが少し得ているのを見ますが、それはスピナーの場合です: 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 が 2 回読み込まれているように見えるため、クラッシュが発生しました。その理由はわかりません。オブザーバーを削除する必要があるというエラーが発生します。これが私のコードです。

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を使用すると、これは私が持っているものですが、1つのWebビューではなく2つのビューが表示されます

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

3 に答える 3

59

GitHub のKINWebBrowserをチェックして、以下のソリューションの完全な実装を確認してください。

estimatedProgressリンク先のプロパティのドキュメントをよく見ると、次のWKWebViewことがわかります。

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

これは、プロパティのキー値監視を設定して、その値estimatedProgressの変化を監視できることを意味します。メソッドからobserveValueForKeyPathUI を更新できます。

Cocoa の KVO 設計パターンはかなり厄介です。Key Value Observingのベスト プラクティスに関する優れた NSHipster の記事をご覧ください。

estimatedProgressonの KVO 実装は次のWKWebViewとおりです。

your から、yourUIViewControllerを設定し、自分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除外するメソッドを設定します。その後、値に直接アクセスして、それに応じて UI を更新できます。estimatedProgresswebViewestimatedProgress

- (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そのUIViewControllerの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];
}

いくつかの大きなファイルでこの動作を確認するには、この甘い銀河の巨大な画像ファイルを読み込みます。(このファイルは 35MB です。WiFi に接続していることを確認してください!)

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

を使用している場合は、UIProgressView次のコードでサファリのようなフェードアウト効果を実現できます。

- (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];
    }
}
于 2014-10-05T03:31:11.380 に答える