この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
前回
前回の記事 では、WKWebView でWeb ページを表示する部分を解説しました。今回は通信中によくステータスバーに表示するインジケーターの表示方法について解説します。
サンプルプロジェクトを起動してみる
hirai-yuki/WebBrowserSample からサンプルプロジェクトをダウンロードして、Xcode 6 で開き、実行してみましょう(pod installを忘れずに!)。
すると、以下のように Web ページの読み込み中に、ステータスバーにインジケーターが表示されていますね。
このように、サンプルプロジェクトでは、WKWebView で Web ページを読み込んでいる最中に、ステータスバーにインジケーターを表示するようにしています。
それでは早速ソースコードを見てみましょう。
ソースコードを見る
と言っても、インジケーターの表示に関する記述は以下の3箇所しかありません。
CLMWebBrowserViewController.m WKWebView クラスの loading プロパティの変更を監視(KVO)
- (void)viewDidLoad
{
[super viewDidLoad];
// WKWebView インスタンスのプロパティの変更を監視する
[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
[self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil];
[self.webView addObserver:self forKeyPath:@"loading" options:NSKeyValueObservingOptionNew context:nil];
[self.webView addObserver:self forKeyPath:@"canGoBack" options:NSKeyValueObservingOptionNew context:nil];
[self.webView addObserver:self forKeyPath:@"canGoForward" options:NSKeyValueObservingOptionNew context:nil];
// 初回画面表示時にIntialURLで指定した Web ページを読み込む
NSURL *url = [NSURL URLWithString:InitialURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
- (void)dealloc
{
// WKWebView インスタンスのプロパティの変更を監視を解除する
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
[self.webView removeObserver:self forKeyPath:@"title"];
[self.webView removeObserver:self forKeyPath:@"loading"];
[self.webView removeObserver:self forKeyPath:@"canGoBack"];
[self.webView removeObserver:self forKeyPath:@"canGoForward"];
}
CLMWebBrowserViewController.m インジケーターの表示/非表示を切り替えてるところ
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqualToString:@"estimatedProgress"]) {
// estimatedProgressが変更されたら、プログレスバーを更新する
[self.navigationController setSGProgressPercentage:self.webView.estimatedProgress * 100.0f];
} else if ([keyPath isEqualToString:@"title"]) {
// titleが変更されたら、ナビゲーションバーのタイトルを設定する
self.title = self.webView.title;
} else if ([keyPath isEqualToString:@"loading"]) {
// loadingが変更されたら、ステータスバーのインジケーターの表示・非表示を切り替える
[UIApplication sharedApplication].networkActivityIndicatorVisible = self.webView.loading;
// リロードボタンと読み込み停止ボタンの有効・無効を切り替える
self.reloadButton.enabled = !self.webView.loading;
self.stopButton.enabled = self.webView.loading;
} else if ([keyPath isEqualToString:@"canGoBack"]) {
// canGoBackが変更されたら、「<」ボタンの有効・無効を切り替える
self.backButton.enabled = self.webView.canGoBack;
} else if ([keyPath isEqualToString:@"canGoForward"]) {
// canGoForwardが変更されたら、「>」ボタンの有効・無効を切り替える
self.forwardButton.enabled = self.webView.canGoForward;
}
}
ご存知の方も多いと思いますが、そもそも、ステータスバーにインジケーターを表示するには、以下のように書きます。
// ステータスバーにインジケーターを表示する
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// ステータスバーのインジケーターを非表示にする
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
サンプルプロジェクトで行なっていることを簡単に説明すると、「WKWebView クラスの loading プロパティの変更を監視して、ローディング中であればインジケーターを表示、そうでなければ非表示にする」ということをやっています。
WKWebView では loading が KVO に準拠した
サンプルプロジェクトだけ見ると、簡単なことしかやっていないように見えますが、実は非常に重要な点があります。 それは、WKWebView では loadingプロパティ が KVO に準拠したプロパティ になったことです。
実は、loading プロパティ自体は UIWebView にもあります。ただ、KVO に準拠していないため、上記のような実装ができませんでした。 なので、変わりに UIWebViewDelegate のメソッドを実装し、 Web ページのロード時・完了時に実行されるデリゲートメソッド内でインジケーターの表示・非表示を切り替えていました。
- (void)webViewDidStartLoad:(UIWebView*)webView
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
- (void)webViewDidFinishLoad:(UIWebView*)webView
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
すごい細かいですが、こんな気の利いた変更もあるんですね!
まとめ
WKWebView では loading プロパティの他にも、KVOに準拠したプロパティがいくつかあります。 次回は、その1つである estimatedProgress プロパティを使用して、プログレスを表示するところを解説します。