Using iOS WKWebView

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.

Display a popup in the Same View Controller

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 
 ) 
  
 ]) 
 } 
  

Display a Popup in a New View Controller

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 
 ]; 
 } 
  

Display a Popup using SwiftUI

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.

Create a Mobile Website
View Site in Mobile | Classic
Share by: