Les exemples suivants représentent un sous-ensemble des options disponibles. Ces exemples doivent être considérés comme des solutions viables minimales pour des circonstances données.
L'utilisation de WKWebView dans ces exemples est limitée à la compatibilité avec le flux Google Pay et n'inclut aucune autre fonctionnalité basée sur WebView.
Faites preuve de discernement et utilisez des personnalisations spécifiques à votre projet lorsque vous implémentez l'une des solutions proposées dans votre projet.
Afficher un pop-up dans le même contrôleur de vue
Cet exemple Swift montre comment une nouvelle WebView (pour un pop-up) peut être affichée dans le même UIViewController couvrant une WebView parente. Pour créer et afficher un pop-up, implémentez la méthode suivante à partir de 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 }
Voici une autre méthode de ce délégué qui permet de supprimer un pop-up de l'écran :
/// 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() }
La fonction addWebView(_ webView: WKWebView) définit également le uiDelegate pour un webView transmis. Voici un exemple d'implémentation :
/// 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) ]) }
Pour les implémentations de contrôleur de vue unique, un bouton "Fermer" doit être ajouté pour permettre aux utilisateurs de fermer les pop-ups (par exemple, une page "Conditions d'utilisation"). Ce bouton peut être placé à différents endroits en fonction de l'interface utilisateur de l'application. Dans l'exemple suivant, le bouton est ajouté directement à la WebView :
/// Adds a "Close" button overlay to the top-trailing corner of a given WebView func addCloseButton(to webView: WKWebView) { let buttonSize = 24.0 let buttonMargin = 6.0 let closeAction = UIAction { [weak self] _ in self?.webViewDidClose(webView) } let closeButton = UIButton(type: .system, primaryAction: closeAction) closeButton.translatesAutoresizingMaskIntoConstraints = false var config = UIButton.Configuration.filled() config.baseBackgroundColor = .systemFill.withAlphaComponent(0.5) config.baseForegroundColor = .systemBackground config.buttonSize = .medium config.cornerStyle = .capsule config.image = UIImage(systemName: "xmark", withConfiguration: UIImage.SymbolConfiguration(pointSize: buttonSize / 2, weight: .bold)) closeButton.configuration = config webView.addSubview(closeButton) NSLayoutConstraint.activate([ closeButton.topAnchor.constraint(equalTo: webView.safeAreaLayoutGuide.topAnchor, constant: buttonMargin), closeButton.trailingAnchor.constraint(equalTo: webView.safeAreaLayoutGuide.trailingAnchor, constant: -buttonMargin), closeButton.widthAnchor.constraint(equalToConstant: buttonSize), closeButton.heightAnchor.constraint(equalToConstant: buttonSize) ]) }
Afficher un pop-up dans un nouveau contrôleur de vue
Cet exemple Objective-C montre comment une nouvelle WebView (pour un pop-up) peut être affichée dans un nouveau contrôleur de vue (qui peut être utilisé si votre application prend en charge les onglets).
Comme l'une des options, ce contrôleur de vue peut avoir un initialiseur qui accepte une instance WKWebView externe :
/// Creates a view controller with a given WebView - (instancetype)initWithWebView:(WKWebView *)webView { if (self = [super init]) { self.webView = webView; } return self; }
Pour créer et afficher un pop-up, implémentez la méthode suivante à partir de 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; }
Voici une autre méthode de ce délégué qui permet de supprimer un pop-up de l'écran :
/// Dismisses the current view controller (after popup was closed) - (void)webViewDidClose:(WKWebView *)webView { [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; }
Afficher un pop-up à l'aide de SwiftUI
Cet exemple SwiftUI montre comment une nouvelle WebView (pour un pop-up) peut être affichée dans la même vue Swift couvrant une WebView parente. Comme WKWebView est un composant UIKit, encapsulez-le dans 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) } }
L'extrait de code inclut à la fois le wrapper UIViewRepresentable pour une WebView et une classe Coordinator personnalisée capable de gérer les événements délégués WebView.
Lorsqu'un pop-up est demandé, il est créé et placé en haut d'une WebView parente. Lors d'un événement de fermeture de pop-up, il est supprimé de la hiérarchie des vues.