Skip to content

Commit

Permalink
feat: HCaptcha.redrawView (#140)
Browse files Browse the repository at this point in the history
* feat: HCaptcha.redrawView

* test: HCaptcha.redrawView

* Apply suggestions from code review

* chore: add comment to moveHCaptchaUp

* Update Example/HCaptcha/ViewController.swift

* Update README.md

---------

Co-authored-by: e271828- <[email protected]>
  • Loading branch information
CAMOBAP and e271828- authored Feb 24, 2024
1 parent 630dd11 commit 8998824
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
29 changes: 29 additions & 0 deletions Example/HCaptcha/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import HCaptcha
import RxCocoa
import RxSwift
import UIKit
import WebKit

class ViewController: UIViewController {
private struct Constants {
Expand All @@ -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 {
Expand Down Expand Up @@ -90,6 +92,12 @@ class ViewController: UIViewController {
print("onEvent error: \(String(describing: error))")
}

if event == .open {
self?.challengeShown = true
/// redrawView call is not required, included for demo purposes
self?.hcaptcha.redrawView()
}

let alertController = UIAlertController(title: "On Event",
message: event.rawValue,
preferredStyle: .alert)
Expand Down Expand Up @@ -131,6 +139,7 @@ class ViewController: UIViewController {
self?.view.viewWithTag(Constants.webViewTag)
}
.subscribe(onNext: { subview in
self.challengeShown = false
subview?.removeFromSuperview()
})
.disposed(by: disposeBag)
Expand Down Expand Up @@ -169,6 +178,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

Expand All @@ -187,4 +200,20 @@ class ViewController: UIViewController {
self?.view.addSubview(label)
}
}

/**
Move hCaptcha WebView frame to the top part of the screen
*/
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
)
}
}
24 changes: 24 additions & 0 deletions Example/HCaptcha_Tests/Core/HCaptcha__Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,30 @@ class HCaptcha__Tests: XCTestCase {
}
wait(for: [exp], timeout: 10)
}

func test__reconfigure() {
let exp = expectation(description: "configureWebView called twice")
var configureCounter = 0
let hcaptcha = HCaptcha(manager: HCaptchaWebViewManager(messageBody: "{action: \"showHCaptcha\"}"))
hcaptcha.configureWebView { _ in
configureCounter += 1
if configureCounter == 2 {
exp.fulfill()
}
}
hcaptcha.didFinishLoading {
let view = UIApplication.shared.windows.first?.rootViewController?.view
hcaptcha.onEvent { e, _ in
if e == .open {
hcaptcha.redrawView()
}
}
hcaptcha.validate(on: view!) { _ in
XCTFail("Should not be called")
}
}
wait(for: [exp], timeout: 10)
}
}


Expand Down
10 changes: 10 additions & 0 deletions HCaptcha/Classes/HCaptcha.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 hCaptcha frame](#change-hcaptcha-frame)
* [Known issues](#known-issues)
* [License](#license)
* [Troubleshooting](#troubleshooting)
Expand Down Expand Up @@ -311,6 +312,45 @@ hcaptcha.validate(on: view, resetOnError: false) { result in
}
```

### Change hCaptcha frame

If you are customizing display beyond the defaults and need to resize or change the hCaptcha layout, for example after a visual challenge appears, you can use the following approach to trigger a redraw of the view:

``` 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)
Expand Down

0 comments on commit 8998824

Please sign in to comment.