From e1e41ec1d99d056a062d885b715fc0e8eb48b16c Mon Sep 17 00:00:00 2001 From: Alexande B Date: Wed, 21 Feb 2024 23:57:19 +0100 Subject: [PATCH] feat: HCaptcha.redrawView --- Example/HCaptcha/ViewController.swift | 25 +++++++++++++++++ HCaptcha/Classes/HCaptcha.swift | 10 +++++++ README.md | 40 +++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/Example/HCaptcha/ViewController.swift b/Example/HCaptcha/ViewController.swift index 399cc79..9c117ff 100644 --- a/Example/HCaptcha/ViewController.swift +++ b/Example/HCaptcha/ViewController.swift @@ -10,6 +10,7 @@ import HCaptcha import RxCocoa import RxSwift import UIKit +import WebKit class ViewController: UIViewController { private struct Constants { @@ -21,6 +22,7 @@ class ViewController: UIViewController { private var disposeBag = DisposeBag() private var locale: Locale? + private var challengeShown: Bool = false /// Don't init SDK to avoid unnecessary API calls and simplify debugging if the application used as a host for tests private var unitTesting: Bool { @@ -90,6 +92,11 @@ class ViewController: UIViewController { print("onEvent error: \(String(describing: error))") } + if event == .open { + self?.challengeShown = true + self?.hcaptcha.redrawView() + } + let alertController = UIAlertController(title: "On Event", message: event.rawValue, preferredStyle: .alert) @@ -131,6 +138,7 @@ class ViewController: UIViewController { self?.view.viewWithTag(Constants.webViewTag) } .subscribe(onNext: { subview in + self.challengeShown = false subview?.removeFromSuperview() }) .disposed(by: disposeBag) @@ -169,6 +177,10 @@ class ViewController: UIViewController { hcaptcha = try! HCaptcha(locale: locale) hcaptcha.configureWebView { [weak self] webview in + if self?.challengeShown == true { + self?.moveHCaptchaUp(webview) + return + } webview.frame = self?.view.bounds ?? CGRect.zero webview.tag = Constants.webViewTag @@ -187,4 +199,17 @@ class ViewController: UIViewController { self?.view.addSubview(label) } } + + private func moveHCaptchaUp(_ webview: WKWebView) { + let padding: CGFloat = 0 + let windowHeight = view.frame.size.height + let targetHeight = (2.0 / 3.0) * windowHeight + + webview.frame = CGRect( + x: padding, + y: padding, + width: view.frame.size.width - 2 * padding, + height: targetHeight - 2 * padding + ) + } } diff --git a/HCaptcha/Classes/HCaptcha.swift b/HCaptcha/Classes/HCaptcha.swift index 8d4b106..7921524 100644 --- a/HCaptcha/Classes/HCaptcha.swift +++ b/HCaptcha/Classes/HCaptcha.swift @@ -206,6 +206,16 @@ public class HCaptcha: NSObject { manager.onDidFinishLoading = closure } + /** + Request for a call to the `configureWebView` closure. + + This may be useful if you need to modify the layout of hCaptcha. + */ + @objc + public func redrawView() { + manager.configureWebView?(manager.webView) + } + // MARK: - Development #if DEBUG diff --git a/README.md b/README.md index cebec1e..f078032 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ + [Using landscape instead of portrait orientation](#using-landscape-instead-of-portrait-orientation) + [SDK Events](#sdk-events) + [Disable new token fetch on expiry](#disable-new-token-fetch-on-expiry) + + [Change hCaptch frame](#change-hcaptcha-frame) * [Known issues](#known-issues) * [License](#license) * [Troubleshooting](#troubleshooting) @@ -311,6 +312,45 @@ hcaptcha.validate(on: view, resetOnError: false) { result in } ``` +### Change hCaptch frame + +In case if you need to change hCaptcha layout for example after visual challenge appear you can use approach above + +``` swift +let hcaptcha = try? HCaptcha(...) +var visualChallengeShown = false +... +hcaptcha?.configureWebView { [weak self] webview in + webview.tag = "hCaptchaViewTag" + if visualChallengeShown { + let padding = 10 + webview.frame = CGRect( + x: padding, + y: padding, + width: view.frame.size.width - 2 * padding, + height: targetHeight - 2 * padding + ) + } else { + webview.frame = self?.view.bounds ?? CGRect.zero + } +} +... +hcaptcha.onEvent { (event, data) in + if event == .open { + visualChallengeShown = true + hcaptcha.redrawView*() + } else if event == .error { + let error = data as? HCaptchaError + print("onEvent error: \(String(describing: error))") + ... + } +} +... +hcaptcha.validate(on: view, resetOnError: false) { result in + visualChallengeShown = false +} +``` + ### SwiftUI Example `HCaptcha` was originally designed to be used with UIKit. But you can easily use it with `SwiftUI` as well. Check out the [SwiftUI Example](./Example/SwiftUI)