既に何人もの方がWKWebViewに関する記事を書いていますが、ハマった事があったので…意外な事にこの件に触れている記事を見かけなかったので。
普通にWKWebViewをメインのViewにしている時には問題が無いのですが、segueで表示された画面がWKWebViewを使っていた時に、NavigationContollerの戻るをタップすると、アプリがクラッシュしました。
WKWebViewは遷移された先のViewControllerで
- (void)viewDidLoad {
[super viewDidLoad];
// configurationの作成
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.allowsInlineMediaPlayback = YES;
configuration.allowsAirPlayForMediaPlayback = YES;
configuration.requiresUserActionForMediaPlayback = YES;
configuration.allowsPictureInPictureMediaPlayback = YES;
webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
webView.translatesAutoresizingMaskIntoConstraints = NO;
webView.allowsLinkPreview = YES;
webView.allowsBackForwardNavigationGestures = YES;
[_childView addSubview:webView];
webView.navigationDelegate = self;
webView.UIDelegate = self;
// Autolayout
NSDictionary *views = NSDictionaryOfVariableBindings(webView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[webView(>=0)]-0-|"
options:0
metrics:nil
views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[webView(>=0)]-0-|" options:0
metrics:nil
views:views]];
// Propertiesの監視
[webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
[webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil];
[webView addObserver:self forKeyPath:@"loading" options:NSKeyValueObservingOptionNew context:nil];
[webView addObserver:self forKeyPath:@"canGoBack" options:NSKeyValueObservingOptionNew context:nil];
[webView addObserver:self forKeyPath:@"canGoForward" options:NSKeyValueObservingOptionNew context:nil];
_backButton.enabled = NO;
_forwardButton.enabled = NO;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com"]]];
}
として初期化したとします。
このViewControllerが消える時に
- (void)viewDidDisappear:(BOOL)animated
{
webView.navigationDelegate = nil;
webView.UIDelegate = nil;
}
とすれば大丈夫!みたいな記述が多いのですが、実は
- (void)viewDidDisappear:(BOOL)animated
{
[webView removeObserver:self];
webView.navigationDelegate = nil;
webView.UIDelegate = nil;
}
の様にプロパティ監視をしているObserver
のremove
も必要になります。