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,["# Using iOS WKWebView\n\nThe 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-------------------------------------------\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----------------------------------------\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-----------------------------\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."]]