Die folgenden Beispiele stellen eine Teilmenge der verfügbaren Optionen dar. Diese Beispiele sollten als Mindestlösungen für die jeweiligen Umstände betrachtet werden.
Die WKWebView-Nutzung in diesen Beispielen ist auf die Unterstützung des Google Pay-Ablaufs beschränkt und umfasst keine zusätzlichen WebView-basierten Funktionen.
Treffen Sie Ihre eigenen Entscheidungen und berücksichtigen Sie projektspezifische Anpassungen, wenn Sie eine der bereitgestellten Lösungen in Ihrem Projekt implementieren.
Pop-up im selben Ansichts-Controller anzeigen
In diesem Swift-Beispiel wird gezeigt, wie eine neue WebView (für ein Pop-up) in derselben UIViewController angezeigt werden kann, die eine übergeordnete WebView abdeckt. Implementieren Sie die folgende Methode aus WKUIDelegate, um ein Pop-up zu erstellen und anzuzeigen:
/// 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 }
Außerdem gibt es eine weitere Methode dieses Delegates, mit der ein Pop-up vom Bildschirm entfernt wird:
/// 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() }
Die Funktion addWebView(_ webView: WKWebView) legt auch die uiDelegate für ein übergebenes webView fest. Hier ein Beispiel für die Implementierung:
/// 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) ]) }
Bei Implementierungen mit einem einzelnen View-Controller sollte eine Schaltfläche zum Schließen hinzugefügt werden, damit Nutzer Pop-ups schließen können (z.B. eine Seite mit den Nutzungsbedingungen). Diese Schaltfläche kann je nach Benutzeroberfläche der App an verschiedenen Stellen platziert werden. Im folgenden Beispiel wird die Schaltfläche direkt in die WebView eingefügt:
/// 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) ]) }
Pop-up in einem neuen View-Controller anzeigen
In diesem Objective-C-Beispiel wird gezeigt, wie ein neues WebView (für ein Pop-up) in einem neuen View-Controller angezeigt werden kann (was verwendet werden könnte, wenn Ihre App Tabs unterstützt).
Als eine der Optionen könnte dieser Ansichtscontroller einen Initialisierer haben, der eine externe WKWebView-Instanz akzeptiert:
/// Creates a view controller with a given WebView - (instancetype)initWithWebView:(WKWebView *)webView { if (self = [super init]) { self.webView = webView; } return self; }
Implementieren Sie die folgende Methode aus WKUIDelegate, um ein Pop-up zu erstellen und anzuzeigen:
/// 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; }
Außerdem gibt es eine weitere Methode dieses Delegates, mit der ein Pop-up vom Bildschirm entfernt wird:
/// Dismisses the current view controller (after popup was closed) - (void)webViewDidClose:(WKWebView *)webView { [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; }
Pop-up mit SwiftUI anzeigen
In diesem SwiftUI-Beispiel wird gezeigt, wie eine neue WebView (für ein Pop-up) in derselben Swift-Ansicht angezeigt werden kann, die eine übergeordnete WebView abdeckt. Da WKWebView eine UIKit-Komponente ist, muss sie in UIViewRepresentable eingeschlossen werden:
/// 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) } }
Das Code-Snippet enthält sowohl den UIViewRepresentable-Wrapper für eine WebView als auch eine benutzerdefinierte Coordinator-Klasse, die WebView-Delegatereignisse verarbeiten kann.
Wenn ein Pop-up angefordert wird, wird es erstellt und oben in einem übergeordneten WebView platziert. Bei einem Ereignis zum Schließen eines Pop-ups wird es aus der Ansichtshierarchie entfernt.