WKWebView handling popup windows

WKWebViewWithPopUp

WKWebView handling pop-up windows

Property

If there is a pop-up window, use the pop-up window. If there is no pop-up window, use the default web view as the current webView.

var popupWebViews = [WKWebView]()
var currentWebView: WKWebView {
    return popupWebViews.isEmpty ? webView : popupWebViews.last!
}

Settings

1. configure javaScript

if #available(iOS 14, *) {
    let preferences = WKWebpagePreferences()
    preferences.allowsContentJavaScript = true
    webView.configuration.defaultWebpagePreferences = preferences
}
else {
    webView.configuration.preferences.javaScriptEnabled = true
    /// user interaction없이 윈도우 창을 열 수 있는지 여부를 나타냄. iOS에서는 기본값이 false이다.
    webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
}

2. back and forward button

func configureBackwardAndForwardButton() {
    /// webView가 뒤로 이동할 수 있거나 팝업창이 있는 경우 뒤로가기 활성화
    backwardButton.isEnabled = currentWebView.canGoBack || popupWebViews.count > 0
    /// webView가 앞으로 이동할 수 있는 경우 활성화
    forwardButton.isEnabled = currentWebView.canGoForward
}

3. backward button action

@IBAction func tapBackwardButton(_ sender: UIBarButtonItem) {
    if currentWebView.canGoBack {
        currentWebView.goBack()
        return
    }

    if popupWebViews.count > 0 {
        let last = popupWebViews.popLast()
        last?.removeFromSuperview()
        /// webView 로드가 완료되면 버튼을 재설정하기는 하지만
        /// 팝업창을 뒤로가기할 경우(닫을 경우) 로드 완료 delegate가 호출되지 않기 때문에 이곳에서 버튼을 재설정한다.
        configureBackwardAndForwardButton()
    }
}

4. create new pop-up

func createNewWebView(_ config: WKWebViewConfiguration) -> WKWebView {
    let newWebView = WKWebView(frame: webView.frame,
                           configuration: config)
    newWebView.navigationDelegate = self
    newWebView.uiDelegate = self
    newWebView.allowsBackForwardNavigationGestures = true
    view.addSubview(newWebView)
    popupWebViews.append(newWebView)
    return newWebView
}

Delegate

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
    /// 팝업창(새 탭) 처리
    print("--->[createWebViewWith configuration]")
    return createNewWebView(configuration)
}

GitHub

View Github