From 4aa79258d7faf395e98da89aa3602452946ed9b7 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Fri, 25 Oct 2024 18:52:22 -0400 Subject: [PATCH 01/12] added UIView+Ext --- Sources/KlaviyoUI/Utilities/UIView+Ext.swift | 36 ++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Sources/KlaviyoUI/Utilities/UIView+Ext.swift diff --git a/Sources/KlaviyoUI/Utilities/UIView+Ext.swift b/Sources/KlaviyoUI/Utilities/UIView+Ext.swift new file mode 100644 index 00000000..f0a0c820 --- /dev/null +++ b/Sources/KlaviyoUI/Utilities/UIView+Ext.swift @@ -0,0 +1,36 @@ +// +// UIView+Ext.swift +// klaviyo-swift-sdk +// +// Created by Andrew Balmer on 10/25/24. +// + +import UIKit + +extension UIView { + /// Pins the view to the edges of the parent view. + /// - Parameter parentView: The parent view to pin this view to. + func pin(to parentView: UIView) { + translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + leadingAnchor.constraint(equalTo: parentView.leadingAnchor), + trailingAnchor.constraint(equalTo: parentView.trailingAnchor), + topAnchor.constraint(equalTo: parentView.topAnchor), + bottomAnchor.constraint(equalTo: parentView.bottomAnchor) + ]) + } + + /// Pins the view to the edges of the given safe area with optional insets. + /// - Parameters: + /// - safeArea: The UILayoutGuide (usually `view.safeAreaLayoutGuide`) to pin the view to. + /// - insets: Optional insets for each side, default is `.zero`. + func pin(to safeArea: UILayoutGuide, insets: NSDirectionalEdgeInsets = .zero) { + translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + topAnchor.constraint(equalTo: safeArea.topAnchor, constant: insets.top), + leadingAnchor.constraint(equalTo: safeArea.leadingAnchor, constant: insets.leading), + bottomAnchor.constraint(equalTo: safeArea.bottomAnchor, constant: -insets.bottom), + trailingAnchor.constraint(equalTo: safeArea.trailingAnchor, constant: -insets.trailing) + ]) + } +} From cd26f328eae8458310eeb61f7e004a56283bfa41 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Fri, 25 Oct 2024 18:53:43 -0400 Subject: [PATCH 02/12] added `PreviewGridViewController` --- .../PreviewGridViewController.swift | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Sources/KlaviyoUI/KlaviyoWebView/Development Assets/PreviewGridViewController.swift diff --git a/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/PreviewGridViewController.swift b/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/PreviewGridViewController.swift new file mode 100644 index 00000000..e184ccd5 --- /dev/null +++ b/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/PreviewGridViewController.swift @@ -0,0 +1,65 @@ +// +// PreviewGridViewController.swift +// klaviyo-swift-sdk +// +// Created by Andrew Balmer on 10/23/24. +// + +#if DEBUG +import Foundation +import UIKit + +/// A sample grid view with randomly-colored tiles for internal Xcode preview purposes only. +class PreviewGridViewController: UIViewController, UICollectionViewDataSource { + var collectionView: UICollectionView! + + override func viewDidLoad() { + super.viewDidLoad() + + let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1.0)) + let item = NSCollectionLayoutItem(layoutSize: itemSize) + let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(0.4)) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) + group.interItemSpacing = .flexible(12) + let section = NSCollectionLayoutSection(group: group) + section.interGroupSpacing = 12 + section.contentInsets = .init(top: 0, leading: 16, bottom: 0, trailing: 16) + + let layout = UICollectionViewCompositionalLayout(section: section) + + collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell") + collectionView.dataSource = self + + view.addSubview(collectionView) + + // Disable autoresizing mask translation for Auto Layout + collectionView.translatesAutoresizingMaskIntoConstraints = false + + // Set up constraints using safeAreaLayoutGuide + NSLayoutConstraint.activate([ + collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + collectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), + collectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), + collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) + ]) + } + + // MARK: UICollectionViewDataSource + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + 12 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) + cell.backgroundColor = UIColor( + red: .random(in: 0...1), + green: .random(in: 0...1), + blue: .random(in: 0...1), + alpha: 1.0) + cell.layer.cornerRadius = 12.0 + return cell + } +} +#endif From 1f34ccbce2ca30041edcdf7c2a8cbc5ed10dbbe0 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Fri, 25 Oct 2024 18:53:55 -0400 Subject: [PATCH 03/12] added PreviewTabViewController --- .../PreviewTabViewController.swift | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Sources/KlaviyoUI/KlaviyoWebView/Development Assets/PreviewTabViewController.swift diff --git a/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/PreviewTabViewController.swift b/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/PreviewTabViewController.swift new file mode 100644 index 00000000..ad667b67 --- /dev/null +++ b/Sources/KlaviyoUI/KlaviyoWebView/Development Assets/PreviewTabViewController.swift @@ -0,0 +1,36 @@ +// +// PreviewTabViewController.swift +// klaviyo-swift-sdk +// +// Created by Andrew Balmer on 10/23/24. +// + +#if DEBUG +import Foundation +import UIKit + +/// A sample tab view for internal Xcode preview purposes only. +class PreviewTabViewController: UITabBarController { + override func viewDidLoad() { + super.viewDidLoad() + + let firstVC = PreviewGridViewController() + let secondVC = UIViewController() + let thirdVC = UIViewController() + + firstVC.title = "Browse" + + firstVC.tabBarItem = UITabBarItem(title: "Browse", image: UIImage(systemName: "house"), tag: 0) + secondVC.tabBarItem = UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass"), tag: 1) + thirdVC.tabBarItem = UITabBarItem(title: "Profile", image: UIImage(systemName: "person"), tag: 2) + + viewControllers = [ + UINavigationController(rootViewController: firstVC), + UINavigationController(rootViewController: secondVC), + UINavigationController(rootViewController: thirdVC) + ] + + firstVC.navigationController?.navigationBar.prefersLargeTitles = true + } +} +#endif From fe1ba9ef74d3b7f524a87456d3a60b5481771476 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Fri, 25 Oct 2024 19:00:13 -0400 Subject: [PATCH 04/12] moved `configureSubviewConstraints()` --- Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift index a2198d08..03e959e7 100644 --- a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewController.swift @@ -37,9 +37,9 @@ class KlaviyoWebViewController: UIViewController, WKUIDelegate { view.addSubview(webView) + configureSubviewConstraints() configureLoadScripts() configureScriptEvaluator() - configureSubviewConstraints() } override func viewDidLoad() { From 11b249b9f331187f54263a461d167bb6f3045d99 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Mon, 28 Oct 2024 11:03:00 -0400 Subject: [PATCH 05/12] added ShadowStyle --- Sources/KlaviyoUI/Styles/ShadowStyle.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Sources/KlaviyoUI/Styles/ShadowStyle.swift diff --git a/Sources/KlaviyoUI/Styles/ShadowStyle.swift b/Sources/KlaviyoUI/Styles/ShadowStyle.swift new file mode 100644 index 00000000..4d00433a --- /dev/null +++ b/Sources/KlaviyoUI/Styles/ShadowStyle.swift @@ -0,0 +1,15 @@ +// +// ShadowStyle.swift +// klaviyo-swift-sdk +// +// Created by Andrew Balmer on 10/28/24. +// + +import UIKit + +public struct ShadowStyle { + let color: CGColor + let opacity: Float + let offset: CGSize + let radius: CGFloat +} From d1bf41ad72da31cd296d9afd71945f9125d198b2 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Mon, 28 Oct 2024 12:28:44 -0400 Subject: [PATCH 06/12] added `KlaviyoWebWrapperStyle` --- .../KlaviyoWebWrapperStyle.swift | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperStyle.swift diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperStyle.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperStyle.swift new file mode 100644 index 00000000..2bfc2b4e --- /dev/null +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperStyle.swift @@ -0,0 +1,32 @@ +// +// KlaviyoWebWrapperStyle.swift +// klaviyo-swift-sdk +// +// Created by Andrew Balmer on 10/28/24. +// + +import UIKit + +public struct KlaviyoWebWrapperStyle { + public enum BackgroundStyle { + case blurred(effect: UIBlurEffect.Style) + case tinted(color: UIColor = .black, opacity: Float) + } + + var backgroundStyle: BackgroundStyle + var insets: NSDirectionalEdgeInsets + var cornerRadius: CGFloat + var shadowStyle: ShadowStyle? +} + +extension KlaviyoWebWrapperStyle { + static var `default` = Self( + backgroundStyle: .blurred(effect: .systemUltraThinMaterialDark), + insets: NSDirectionalEdgeInsets(top: 24, leading: 36, bottom: 24, trailing: 36), + cornerRadius: 16.0, + shadowStyle: .init( + color: UIColor.black.cgColor, + opacity: 0.5, + offset: CGSize(width: 5, height: 5), + radius: 8)) +} From 0a425856fbf285cadbbe96fadc429c522da5045d Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Mon, 28 Oct 2024 12:29:13 -0400 Subject: [PATCH 07/12] added `default` value to `ShadowStyle` --- Sources/KlaviyoUI/Styles/ShadowStyle.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sources/KlaviyoUI/Styles/ShadowStyle.swift b/Sources/KlaviyoUI/Styles/ShadowStyle.swift index 4d00433a..dbcd20e2 100644 --- a/Sources/KlaviyoUI/Styles/ShadowStyle.swift +++ b/Sources/KlaviyoUI/Styles/ShadowStyle.swift @@ -13,3 +13,11 @@ public struct ShadowStyle { let offset: CGSize let radius: CGFloat } + +extension ShadowStyle { + public static var `default`: Self = .init( + color: UIColor.black.cgColor, + opacity: 0.5, + offset: CGSize(width: 5, height: 5), + radius: 8) +} From 99ca75a32184b1b9bb388ad295f2d70034a89c57 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Mon, 28 Oct 2024 12:30:37 -0400 Subject: [PATCH 08/12] implemented `KlaviyoWebWrapperViewController` --- .../KlaviyoWebViewWrapper.swift | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewWrapper.swift diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewWrapper.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewWrapper.swift new file mode 100644 index 00000000..a4dec177 --- /dev/null +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewWrapper.swift @@ -0,0 +1,152 @@ +// +// File.swift +// klaviyo-swift-sdk +// +// Created by Andrew Balmer on 10/22/24. +// + +import Foundation +import UIKit + +public class KlaviyoWebWrapperViewController: UIViewController { + // MARK: - Properties + + let viewModel: KlaviyoWebViewModeling + let style: KlaviyoWebWrapperStyle + + // MARK: - Subviews + + private lazy var blurEffectView: UIVisualEffectView? = { + guard case let .blurred(effect) = style.backgroundStyle else { return nil } + + let blurEffect = UIBlurEffect(style: effect) + let blurEffectView = UIVisualEffectView(effect: blurEffect) + + return blurEffectView + }() + + private lazy var tintView: UIView? = { + guard case let .tinted(color, opacity) = style.backgroundStyle else { return nil } + + let tintView = UIView() + tintView.backgroundColor = color + tintView.layer.opacity = opacity + + return tintView + }() + + private lazy var shadowContainerView: UIView? = { + guard let shadowProperties = style.shadowStyle else { return nil } + + let shadowContainerView = UIView() + + shadowContainerView.layer.shadowColor = shadowProperties.color + shadowContainerView.layer.shadowOpacity = shadowProperties.opacity + shadowContainerView.layer.shadowOffset = shadowProperties.offset + shadowContainerView.layer.shadowRadius = shadowProperties.radius + + shadowContainerView.layer.masksToBounds = false + + return shadowContainerView + }() + + private lazy var webViewController: KlaviyoWebViewController = { + let webViewController = KlaviyoWebViewController(viewModel: viewModel) + guard let webView = webViewController.view else { return webViewController } + webView.layer.cornerRadius = 16 + webView.layer.masksToBounds = true + + return webViewController + }() + + // MARK: - View Initialization + + init(viewModel: KlaviyoWebViewModeling, style: KlaviyoWebWrapperStyle = .default) { + self.viewModel = viewModel + self.style = style + + super.init(nibName: nil, bundle: nil) + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override public func viewDidLoad() { + super.viewDidLoad() + loadSubviews() + } + + func loadSubviews() { + if let blurEffectView { + view.addSubview(blurEffectView) + blurEffectView.pin(to: view) + } + + if let tintView { + view.addSubview(tintView) + tintView.pin(to: view) + } + + guard let webView = webViewController.view else { return } + let webViewInsets = style.insets + + if let shadowContainerView { + view.addSubview(shadowContainerView) + shadowContainerView.addSubview(webView) + + shadowContainerView.pin(to: view.safeAreaLayoutGuide, insets: webViewInsets) + webView.pin(to: shadowContainerView) + + addChild(webViewController) + webViewController.didMove(toParent: self) + } else { + view.addSubview(webView) + + webView.pin(to: view.safeAreaLayoutGuide, insets: webViewInsets) + + addChild(webViewController) + webViewController.didMove(toParent: self) + } + } +} + +// MARK: - Previews + +#if DEBUG +func createKlaviyoWebPreview(url: URL, style: KlaviyoWebWrapperStyle) -> UIViewController { + let viewModel = KlaviyoWebViewModel(url: url) + let viewController = KlaviyoWebWrapperViewController(viewModel: viewModel, style: style) + + // Add a dummy view in the background to preview what the KlaviyoWebWrapperViewController + // might look like when it's displayed on top of a view in an app. + let childViewController = PreviewTabViewController() + viewController.view.addSubview(childViewController.view) + viewController.view.sendSubviewToBack(childViewController.view) + viewController.addChild(childViewController) + childViewController.didMove(toParent: viewController) + + return viewController +} +#endif + +#if swift(>=5.9) +@available(iOS 17.0, *) +#Preview("Default style") { + let url = URL(string: "https://www.google.com")! + createKlaviyoWebPreview(url: url, style: .default) +} + +@available(iOS 17.0, *) +#Preview("Tinted background") { + let url = URL(string: "https://www.google.com")! + let style = KlaviyoWebWrapperStyle( + backgroundStyle: .tinted(opacity: 0.6), + insets: NSDirectionalEdgeInsets(top: 24, leading: 36, bottom: 24, trailing: 36), + cornerRadius: 24, + shadowStyle: .default) + + createKlaviyoWebPreview(url: url, style: style) +} +#endif From 464d957ad95b2f4520902e22c7aff2afa627160f Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Mon, 28 Oct 2024 13:13:53 -0400 Subject: [PATCH 09/12] renamed file --- ...WebViewWrapper.swift => KlaviyoWebWrapperViewController.swift} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Sources/KlaviyoUI/KlaviyoWebView/{KlaviyoWebViewWrapper.swift => KlaviyoWebWrapperViewController.swift} (100%) diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewWrapper.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift similarity index 100% rename from Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewWrapper.swift rename to Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift From a776f2186c08af8bd6777e3b5cd586c4f1a355b3 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Mon, 28 Oct 2024 14:35:01 -0400 Subject: [PATCH 10/12] fixed Xcode 15.4 build issue --- .../KlaviyoWebView/KlaviyoWebWrapperViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift index a4dec177..4f9183b2 100644 --- a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift @@ -135,7 +135,7 @@ func createKlaviyoWebPreview(url: URL, style: KlaviyoWebWrapperStyle) -> UIViewC @available(iOS 17.0, *) #Preview("Default style") { let url = URL(string: "https://www.google.com")! - createKlaviyoWebPreview(url: url, style: .default) + return createKlaviyoWebPreview(url: url, style: .default) } @available(iOS 17.0, *) @@ -147,6 +147,6 @@ func createKlaviyoWebPreview(url: URL, style: KlaviyoWebWrapperStyle) -> UIViewC cornerRadius: 24, shadowStyle: .default) - createKlaviyoWebPreview(url: url, style: style) + return createKlaviyoWebPreview(url: url, style: style) } #endif From e8ddcbe3c1db515ee35fe26c1920f69098499802 Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Mon, 28 Oct 2024 16:42:42 -0400 Subject: [PATCH 11/12] added `dismiss` method to viewModel --- Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift | 6 ++++++ .../KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModeling.swift | 1 + 2 files changed, 7 insertions(+) diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift index 1f3a6e99..e80e0827 100644 --- a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModel.swift @@ -41,4 +41,10 @@ class KlaviyoWebViewModel: KlaviyoWebViewModeling { func handleScriptMessage(_ message: WKScriptMessage) { // TODO: handle script message } + + // MARK: handle user events + + func dismiss() { + // TODO: handle dismiss + } } diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModeling.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModeling.swift index 5c34cfac..dc725139 100644 --- a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModeling.swift +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebViewModeling.swift @@ -20,4 +20,5 @@ protocol KlaviyoWebViewModeling { func handleNavigationEvent(_ event: WKNavigationEvent) func handleScriptMessage(_ message: WKScriptMessage) + func dismiss() } From c8e303810f77ba042a25a8402ee7c6e58906a5cf Mon Sep 17 00:00:00 2001 From: Andrew Balmer Date: Tue, 29 Oct 2024 17:03:26 -0400 Subject: [PATCH 12/12] added tap gesture recognizer --- .../KlaviyoWebWrapperViewController.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift index 4f9183b2..5e084d13 100644 --- a/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift +++ b/Sources/KlaviyoUI/KlaviyoWebView/KlaviyoWebWrapperViewController.swift @@ -14,6 +14,13 @@ public class KlaviyoWebWrapperViewController: UIViewController { let viewModel: KlaviyoWebViewModeling let style: KlaviyoWebWrapperStyle + private lazy var dismissGestureRecognizer: UITapGestureRecognizer = { + let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleDismissGesture)) + tapRecognizer.numberOfTapsRequired = 1 + tapRecognizer.numberOfTouchesRequired = 1 + return tapRecognizer + }() + // MARK: - Subviews private lazy var blurEffectView: UIVisualEffectView? = { @@ -22,6 +29,8 @@ public class KlaviyoWebWrapperViewController: UIViewController { let blurEffect = UIBlurEffect(style: effect) let blurEffectView = UIVisualEffectView(effect: blurEffect) + blurEffectView.addGestureRecognizer(dismissGestureRecognizer) + return blurEffectView }() @@ -32,6 +41,8 @@ public class KlaviyoWebWrapperViewController: UIViewController { tintView.backgroundColor = color tintView.layer.opacity = opacity + tintView.addGestureRecognizer(dismissGestureRecognizer) + return tintView }() @@ -110,6 +121,12 @@ public class KlaviyoWebWrapperViewController: UIViewController { webViewController.didMove(toParent: self) } } + + // MARK: - user interactions + + @objc private func handleDismissGesture() { + viewModel.dismiss() + } } // MARK: - Previews