Using iOS WKWebView
Stay organized with collections
Save and categorize content based on your preferences.
The following examples represent a subset of available options. These examples should be considered as minimum viable solutions for given circumstances.
WKWebView
usage in these examples is limited to the Google Pay flow support, and does not include any additional WebView-powered capabilities.
Use your own judgement and project-specific customizations when implementing any of provided solutions in your project.
This Swift example is demonstrating how a new WebView (for a popup) could be displayed in the same UIViewController covering a parent WebView.
In order to create and display a popup, implement the following method from WKUIDelegate:
/// Creates a new WebView for displaying a popup
func webView(
_ webView: WKWebView,
createWebViewWith configuration: WKWebViewConfiguration,
for navigationAction: WKNavigationAction,
windowFeatures: WKWindowFeatures) -> WKWebView? {
// If the target of the navigation is a new window (popup), this property is nil
guard navigationAction.targetFrame == nil else { return nil }
// Creates a new WebView for a popup, and displays it in the same view controller (on the top of `mainWebView`)
let popupWebView = WKWebView(frame: .zero, configuration: configuration)
addWebView(popupWebView)
return popupWebView
}
Also, one more method from this delegate which would remove a popup from the screen:
/// Removes the WebView from the view hierarchy and updates the UI as needed (after popup was closed)
func webViewDidClose(_ webView: WKWebView) {
/// Keeping the `mainWebView` on screen, and removing only popups
guard webView != mainWebView else { return }
webView.removeFromSuperview()
}
The function addWebView(_ webView: WKWebView)
is also setting the uiDelegate
for a passed webView
. Here is a sample implementation:
/// Adds a WebView into the view hierarchy
/// Same method is being used for displaying both `mainWebView` and any popups
func addWebView(_ webView: WKWebView) {
webView.uiDelegate = self
webView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(webView)
NSLayoutConstraint.activate([
webView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
webView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
}
This Objective-C example is demonstrating how a new WebView (for a popup) could be displayed in a new view controller (which could be used if your app supports tabs).
As one of the options, this view controller could have an initializer which accepts an external WKWebView
instance:
/// Creates a view controller with a given WebView
- (instancetype)initWithWebView:(WKWebView *)webView {
if (self = [super init]) {
self.webView = webView;
}
return self;
}
In order to create and display a popup, implement the following method from WKUIDelegate:
/// Creates a new WebView for displaying a popup
- (nullable WKWebView *)webView:(WKWebView *)webView
createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration
forNavigationAction:(WKNavigationAction *)navigationAction
windowFeatures:(WKWindowFeatures *)windowFeatures {
// If the target of the navigation is a new window (popup), this property is nil
if (navigationAction.targetFrame != nil) { return nil; }
// Create a new WebView for a popup
WKWebView *popupWebView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
// Create a new instance of `NewViewController` with a newly created WebView, and present it modally
NewViewController *popupViewController = [[NewViewController alloc] initWithWebView:popupWebView];
[self presentViewController:popupViewController animated:YES completion:nil];
return popupWebView;
}
Also, one more method from this delegate which would remove a popup from the screen:
/// Dismisses the current view controller (after popup was closed)
- (void)webViewDidClose:(WKWebView *)webView {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
This SwiftUI example is demonstrating how a new WebView (for a popup) could be displayed in the same Swift View covering a parent WebView.
Since WKWebView is a UIKit component, wrap it into UIViewRepresentable:
/// A SwiftUI wrapper for `WKWebView`
struct WebView: UIViewRepresentable {
/// Underlying WebView
let wkWebView = WKWebView()
/// Loads a given `url` into the underlying WebView
func load(url: URL) -> Self {
wkWebView.load(URLRequest(url: url))
return self
}
/// Creates the view object representing `WKWebView` and configures its initial state
func makeUIView(context: Context) -> some UIView {
wkWebView.uiDelegate = context.coordinator
return wkWebView
}
/// When the state of the app changes, SwiftUI calls this method for any changes affecting
/// the corresponding UIKit viewAs an alternative, this method could be used to load the `url`
/// into the WebView instead of calling `load(url:)` explicitly
func updateUIView(_ uiView: UIViewType, context: Context) { }
/// Creates a bridge between SwiftUI and `WKUIDelegate`
func makeCoordinator() -> WKUIDelegate {
/// A coordinator capable of handling `WKUIDelegate` events
final class Coordinator: NSObject, WKUIDelegate {
/// Main WebView which displays the `url` passed into `SwiftUISurface`
let mainWebView: WebView
/// Creates a coordinator with a given main WebView
init(_ mainWebView: WebView) {
self.mainWebView = mainWebView
}
/// Creates a new WebView for displaying a popup
func webView(
_ webView: WKWebView,
createWebViewWith configuration: WKWebViewConfiguration,
for navigationAction: WKNavigationAction,
windowFeatures: WKWindowFeatures) -> WKWebView? {
// If the target of the navigation is a new window (popup), this property is nil
guard navigationAction.targetFrame == nil else { return nil }
// Creates a new WebView for a popup which would use the same coordinator
let popupWebView = WKWebView(frame: webView.frame, configuration: configuration)
popupWebView.translatesAutoresizingMaskIntoConstraints = false
popupWebView.uiDelegate = webView.uiDelegate
/// Displays the newly created popup WebView on the top of a parent WebView (`mainWebView`)
webView.addSubview(popupWebView)
NSLayoutConstraint.activate([
popupWebView.leadingAnchor.constraint(equalTo: webView.leadingAnchor),
popupWebView.topAnchor.constraint(equalTo: webView.topAnchor),
popupWebView.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
popupWebView.bottomAnchor.constraint(equalTo: webView.bottomAnchor),
])
return popupWebView
}
/// Removes the WebView from the view hierarchy and updates the UI as needed (after popup was closed)
func webViewDidClose(_ webView: WKWebView) {
/// Keeping the `mainWebView` on screen, and removing only popups
guard webView != mainWebView.wkWebView else { return }
webView.removeFromSuperview()
}
}
return Coordinator(self)
}
}
The code snippet includes both UIViewRepresentable
wrapper for a WebView, and a custom Coordinator
class which is capable of handling WebView delegate events.
When a popup requested - it creates it, and places it on the top of a parent WebView. On a popup close event - it removes it from the view hierarchy.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-06-17 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-06-17 UTC."],[],[],null,["The following examples represent a subset of available options. These examples should be considered as minimum viable solutions for given circumstances.\n`WKWebView` usage in these examples is limited to the Google Pay flow support, and does not include any additional WebView-powered capabilities.\nUse your own judgement and project-specific customizations when implementing any of provided solutions in your project.\n| **Note** : Before using this guide, make sure that you have a working [Google Pay Web integration](/pay/api/web/guides/tutorial).\n\nDisplay a popup in the Same View Controller\n\nThis Swift example is demonstrating how a new WebView (for a popup) could be displayed in the same [UIViewController](https://developer.apple.com/documentation/uikit/uiviewcontroller) covering a parent WebView.\nIn order to create and display a popup, implement the following method from [WKUIDelegate](https://developer.apple.com/documentation/webkit/wkuidelegate): \n\n```swift\n/// Creates a new WebView for displaying a popup\nfunc webView(\n _ webView: WKWebView,\n createWebViewWith configuration: WKWebViewConfiguration,\n for navigationAction: WKNavigationAction,\n windowFeatures: WKWindowFeatures) -\u003e WKWebView? {\n\n // If the target of the navigation is a new window (popup), this property is nil\n guard navigationAction.targetFrame == nil else { return nil }\n\n // Creates a new WebView for a popup, and displays it in the same view controller (on the top of `mainWebView`)\n let popupWebView = WKWebView(frame: .zero, configuration: configuration)\n addWebView(popupWebView)\n return popupWebView\n}\n \n```\n\nAlso, one more method from this delegate which would remove a popup from the screen: \n\n```swift\n/// Removes the WebView from the view hierarchy and updates the UI as needed (after popup was closed)\nfunc webViewDidClose(_ webView: WKWebView) {\n /// Keeping the `mainWebView` on screen, and removing only popups\n guard webView != mainWebView else { return }\n\n webView.removeFromSuperview()\n}\n \n```\n\nThe function `addWebView(_ webView: WKWebView)` is also setting the `uiDelegate` for a passed `webView`. Here is a sample implementation: \n\n```swift\n/// Adds a WebView into the view hierarchy\n/// Same method is being used for displaying both `mainWebView` and any popups\nfunc addWebView(_ webView: WKWebView) {\n webView.uiDelegate = self\n webView.translatesAutoresizingMaskIntoConstraints = false\n\n view.addSubview(webView)\n NSLayoutConstraint.activate([\n webView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),\n webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),\n webView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),\n webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)\n ])\n}\n \n```\n\nDisplay a Popup in a New View Controller\n\nThis Objective-C example is demonstrating how a new WebView (for a popup) could be displayed in a new view controller (which could be used if your app supports tabs).\nAs one of the options, this view controller could have an initializer which accepts an external `WKWebView` instance: \n\n```swift\n/// Creates a view controller with a given WebView\n- (instancetype)initWithWebView:(WKWebView *)webView {\n if (self = [super init]) {\n self.webView = webView;\n }\n return self;\n}\n \n```\n\nIn order to create and display a popup, implement the following method from [WKUIDelegate](https://developer.apple.com/documentation/webkit/wkuidelegate): \n\n```swift\n/// Creates a new WebView for displaying a popup\n- (nullable WKWebView *)webView:(WKWebView *)webView\n createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration\n forNavigationAction:(WKNavigationAction *)navigationAction\n windowFeatures:(WKWindowFeatures *)windowFeatures {\n\n // If the target of the navigation is a new window (popup), this property is nil\n if (navigationAction.targetFrame != nil) { return nil; }\n\n // Create a new WebView for a popup\n WKWebView *popupWebView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];\n\n // Create a new instance of `NewViewController` with a newly created WebView, and present it modally\n NewViewController *popupViewController = [[NewViewController alloc] initWithWebView:popupWebView];\n [self presentViewController:popupViewController animated:YES completion:nil];\n\n return popupWebView;\n}\n \n```\n\nAlso, one more method from this delegate which would remove a popup from the screen: \n\n```swift\n/// Dismisses the current view controller (after popup was closed)\n- (void)webViewDidClose:(WKWebView *)webView {\n [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];\n}\n \n```\n\nDisplay a Popup using SwiftUI\n\nThis SwiftUI example is demonstrating how a new WebView (for a popup) could be displayed in the same [Swift View](https://developer.apple.com/documentation/swiftui/view) covering a parent WebView.\nSince [WKWebView](https://developer.apple.com/documentation/webkit/wkwebview) is a [UIKit](https://developer.apple.com/documentation/uikit/uiview) component, wrap it into [UIViewRepresentable](https://developer.apple.com/documentation/swiftui/uiviewrepresentable): \n\n```swift\n/// A SwiftUI wrapper for `WKWebView`\nstruct WebView: UIViewRepresentable {\n\n /// Underlying WebView\n let wkWebView = WKWebView()\n\n /// Loads a given `url` into the underlying WebView\n func load(url: URL) -\u003e Self {\n wkWebView.load(URLRequest(url: url))\n return self\n }\n\n /// Creates the view object representing `WKWebView` and configures its initial state\n func makeUIView(context: Context) -\u003e some UIView {\n wkWebView.uiDelegate = context.coordinator\n return wkWebView\n }\n\n /// When the state of the app changes, SwiftUI calls this method for any changes affecting\n /// the corresponding UIKit viewAs an alternative, this method could be used to load the `url`\n /// into the WebView instead of calling `load(url:)` explicitly\n func updateUIView(_ uiView: UIViewType, context: Context) { }\n\n /// Creates a bridge between SwiftUI and `WKUIDelegate`\n func makeCoordinator() -\u003e WKUIDelegate {\n\n /// A coordinator capable of handling `WKUIDelegate` events\n final class Coordinator: NSObject, WKUIDelegate {\n\n /// Main WebView which displays the `url` passed into `SwiftUISurface`\n let mainWebView: WebView\n\n /// Creates a coordinator with a given main WebView\n init(_ mainWebView: WebView) {\n self.mainWebView = mainWebView\n }\n\n /// Creates a new WebView for displaying a popup\n func webView(\n _ webView: WKWebView,\n createWebViewWith configuration: WKWebViewConfiguration,\n for navigationAction: WKNavigationAction,\n windowFeatures: WKWindowFeatures) -\u003e WKWebView? {\n\n // If the target of the navigation is a new window (popup), this property is nil\n guard navigationAction.targetFrame == nil else { return nil }\n\n // Creates a new WebView for a popup which would use the same coordinator\n let popupWebView = WKWebView(frame: webView.frame, configuration: configuration)\n popupWebView.translatesAutoresizingMaskIntoConstraints = false\n popupWebView.uiDelegate = webView.uiDelegate\n\n /// Displays the newly created popup WebView on the top of a parent WebView (`mainWebView`)\n webView.addSubview(popupWebView)\n NSLayoutConstraint.activate([\n popupWebView.leadingAnchor.constraint(equalTo: webView.leadingAnchor),\n popupWebView.topAnchor.constraint(equalTo: webView.topAnchor),\n popupWebView.trailingAnchor.constraint(equalTo: webView.trailingAnchor),\n popupWebView.bottomAnchor.constraint(equalTo: webView.bottomAnchor),\n ])\n\n return popupWebView\n }\n\n /// Removes the WebView from the view hierarchy and updates the UI as needed (after popup was closed)\n func webViewDidClose(_ webView: WKWebView) {\n /// Keeping the `mainWebView` on screen, and removing only popups\n guard webView != mainWebView.wkWebView else { return }\n\n webView.removeFromSuperview()\n }\n }\n\n return Coordinator(self)\n }\n}\n \n```\n\nThe code snippet includes both `UIViewRepresentable` wrapper for a WebView, and a custom `Coordinator` class which is capable of handling WebView delegate events.\nWhen a popup requested - it creates it, and places it on the top of a parent WebView. On a popup close event - it removes it from the view hierarchy."]]