@jaeyeonee/capacitor-ios-webview 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/docs.json +2 -2
- package/dist/esm/definitions.d.ts +2 -0
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/CustomWebViewPlugin/CustomWebView.swift +108 -35
- package/ios/Sources/CustomWebViewPlugin/CustomWebViewPlugin.swift +5 -2
- package/ios/Sources/CustomWebViewPlugin/CustomWebViewTypes.swift +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,12 +24,12 @@ npx cap sync
|
|
|
24
24
|
### open(...)
|
|
25
25
|
|
|
26
26
|
```typescript
|
|
27
|
-
open(options: { url: string; closeButtonText?: string; }) => Promise<void>
|
|
27
|
+
open(options: { url: string; closeButtonText?: string; closeWarningText?: string; toolbarPosition?: 'top' | 'bottom'; }) => Promise<void>
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
| Param | Type
|
|
31
|
-
| ------------- |
|
|
32
|
-
| **`options`** | <code>{ url: string; closeButtonText?: string; }</code> |
|
|
30
|
+
| Param | Type |
|
|
31
|
+
| ------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
32
|
+
| **`options`** | <code>{ url: string; closeButtonText?: string; closeWarningText?: string; toolbarPosition?: 'top' \| 'bottom'; }</code> |
|
|
33
33
|
|
|
34
34
|
--------------------
|
|
35
35
|
|
package/dist/docs.json
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"methods": [
|
|
8
8
|
{
|
|
9
9
|
"name": "open",
|
|
10
|
-
"signature": "(options: { url: string; closeButtonText?: string; }) => Promise<void>",
|
|
10
|
+
"signature": "(options: { url: string; closeButtonText?: string; closeWarningText?: string; toolbarPosition?: 'top' | 'bottom'; }) => Promise<void>",
|
|
11
11
|
"parameters": [
|
|
12
12
|
{
|
|
13
13
|
"name": "options",
|
|
14
14
|
"docs": "",
|
|
15
|
-
"type": "{ url: string; closeButtonText?: string | undefined; }"
|
|
15
|
+
"type": "{ url: string; closeButtonText?: string | undefined; closeWarningText?: string | undefined; toolbarPosition?: 'top' | 'bottom' | undefined; }"
|
|
16
16
|
}
|
|
17
17
|
],
|
|
18
18
|
"returns": "Promise<void>",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface CustomWebViewPlugin {\n open(options: { url: string
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface CustomWebViewPlugin {\n open(options: { url: string; closeButtonText?: string; closeWarningText?: string; toolbarPosition?: 'top'|'bottom' }): Promise<void>;\n\n close(): Promise<void>;\n}\n"]}
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import UIKit
|
|
2
2
|
import WebKit
|
|
3
3
|
|
|
4
|
-
final class CustomWebViewController: UIViewController,
|
|
4
|
+
final class CustomWebViewController: UIViewController, WKNavigationDelegate {
|
|
5
5
|
|
|
6
6
|
private let url: URL
|
|
7
|
-
private let closeButtonText: String
|
|
7
|
+
private let closeButtonText: String?
|
|
8
|
+
private let closeWarningText: String
|
|
8
9
|
private let webView = WKWebView()
|
|
9
10
|
private var backButton: UIButton!
|
|
11
|
+
private let toolbarPosition: ToolbarPosition
|
|
12
|
+
private let toolbarHeight: CGFloat = 48
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
// gradient view
|
|
15
|
+
private let gradientView = UIView()
|
|
16
|
+
|
|
17
|
+
init(url: URL, closeButtonText: String? = nil, closeWarningText: String? = nil, toolbarPosition: ToolbarPosition = .top) {
|
|
12
18
|
self.url = url
|
|
13
|
-
self.closeButtonText = closeButtonText
|
|
19
|
+
self.closeButtonText = closeButtonText
|
|
20
|
+
self.closeWarningText = closeWarningText ?? "Tap again to close the WebView."
|
|
21
|
+
self.toolbarPosition = toolbarPosition
|
|
14
22
|
super.init(nibName: nil, bundle: nil)
|
|
15
23
|
}
|
|
16
24
|
|
|
@@ -24,12 +32,16 @@ final class CustomWebViewController: UIViewController, UIGestureRecognizerDelega
|
|
|
24
32
|
|
|
25
33
|
setupHeader()
|
|
26
34
|
setupWebView()
|
|
35
|
+
setupGradient()
|
|
27
36
|
load()
|
|
28
37
|
}
|
|
29
38
|
|
|
39
|
+
// MARK: - Header
|
|
40
|
+
|
|
41
|
+
private let header = UIView()
|
|
42
|
+
|
|
30
43
|
private func setupHeader() {
|
|
31
|
-
|
|
32
|
-
header.backgroundColor = .white
|
|
44
|
+
header.backgroundColor = UIColor.systemBackground.withAlphaComponent(0.95)
|
|
33
45
|
header.translatesAutoresizingMaskIntoConstraints = false
|
|
34
46
|
view.addSubview(header)
|
|
35
47
|
|
|
@@ -41,27 +53,45 @@ final class CustomWebViewController: UIViewController, UIGestureRecognizerDelega
|
|
|
41
53
|
self.backButton = back
|
|
42
54
|
|
|
43
55
|
let close = UIButton(type: .system)
|
|
44
|
-
|
|
56
|
+
if let text = closeButtonText, !text.isEmpty {
|
|
57
|
+
close.setTitle(text, for: .normal)
|
|
58
|
+
} else {
|
|
59
|
+
close.setImage(UIImage(systemName: "xmark"), for: .normal)
|
|
60
|
+
}
|
|
45
61
|
close.addTarget(self, action: #selector(closeTapped), for: .touchUpInside)
|
|
46
62
|
close.translatesAutoresizingMaskIntoConstraints = false
|
|
47
63
|
header.addSubview(close)
|
|
48
64
|
|
|
49
65
|
NSLayoutConstraint.activate([
|
|
50
|
-
header.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
|
|
51
|
-
header.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
52
|
-
header.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
53
|
-
header.heightAnchor.constraint(equalToConstant: 48),
|
|
54
|
-
|
|
55
66
|
back.leadingAnchor.constraint(equalTo: header.leadingAnchor, constant: 8),
|
|
56
67
|
back.centerYAnchor.constraint(equalTo: header.centerYAnchor),
|
|
57
68
|
back.widthAnchor.constraint(equalToConstant: 44),
|
|
58
69
|
back.heightAnchor.constraint(equalToConstant: 44),
|
|
59
70
|
|
|
60
|
-
close.
|
|
61
|
-
close.centerYAnchor.constraint(equalTo: header.centerYAnchor)
|
|
71
|
+
close.trailingAnchor.constraint(equalTo: header.trailingAnchor, constant: -8),
|
|
72
|
+
close.centerYAnchor.constraint(equalTo: header.centerYAnchor),
|
|
73
|
+
close.widthAnchor.constraint(equalToConstant: 44),
|
|
74
|
+
close.heightAnchor.constraint(equalToConstant: 44)
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
if toolbarPosition == .top {
|
|
78
|
+
NSLayoutConstraint.activate([
|
|
79
|
+
header.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
|
|
80
|
+
])
|
|
81
|
+
} else {
|
|
82
|
+
NSLayoutConstraint.activate([
|
|
83
|
+
header.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8)
|
|
84
|
+
])
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
NSLayoutConstraint.activate([
|
|
88
|
+
header.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
89
|
+
header.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
90
|
+
header.heightAnchor.constraint(equalToConstant: toolbarHeight)
|
|
62
91
|
])
|
|
63
92
|
}
|
|
64
93
|
|
|
94
|
+
// MARK: - WebView
|
|
65
95
|
|
|
66
96
|
private func setupWebView() {
|
|
67
97
|
webView.translatesAutoresizingMaskIntoConstraints = false
|
|
@@ -69,14 +99,65 @@ final class CustomWebViewController: UIViewController, UIGestureRecognizerDelega
|
|
|
69
99
|
webView.navigationDelegate = self
|
|
70
100
|
view.addSubview(webView)
|
|
71
101
|
|
|
102
|
+
if toolbarPosition == .top {
|
|
103
|
+
NSLayoutConstraint.activate([
|
|
104
|
+
webView.topAnchor.constraint(equalTo: header.bottomAnchor),
|
|
105
|
+
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
|
106
|
+
])
|
|
107
|
+
} else {
|
|
108
|
+
NSLayoutConstraint.activate([
|
|
109
|
+
webView.topAnchor.constraint(equalTo: view.topAnchor),
|
|
110
|
+
webView.bottomAnchor.constraint(equalTo: header.topAnchor)
|
|
111
|
+
])
|
|
112
|
+
}
|
|
113
|
+
|
|
72
114
|
NSLayoutConstraint.activate([
|
|
73
|
-
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 48),
|
|
74
115
|
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
75
|
-
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
|
|
76
|
-
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
|
116
|
+
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
|
|
77
117
|
])
|
|
78
118
|
}
|
|
79
119
|
|
|
120
|
+
// MARK: - Gradient Shadow
|
|
121
|
+
private func setupGradient() {
|
|
122
|
+
gradientView.translatesAutoresizingMaskIntoConstraints = false
|
|
123
|
+
view.addSubview(gradientView)
|
|
124
|
+
|
|
125
|
+
let gradientLayer = CAGradientLayer()
|
|
126
|
+
gradientLayer.colors = [
|
|
127
|
+
UIColor.black.withAlphaComponent(0.05).cgColor,
|
|
128
|
+
UIColor.clear.cgColor
|
|
129
|
+
]
|
|
130
|
+
gradientLayer.cornerRadius = 0
|
|
131
|
+
|
|
132
|
+
let gradientHeight: CGFloat = 6
|
|
133
|
+
|
|
134
|
+
if toolbarPosition == .top {
|
|
135
|
+
gradientView.layer.addSublayer(gradientLayer)
|
|
136
|
+
NSLayoutConstraint.activate([
|
|
137
|
+
gradientView.topAnchor.constraint(equalTo: header.bottomAnchor),
|
|
138
|
+
gradientView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
139
|
+
gradientView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
140
|
+
gradientView.heightAnchor.constraint(equalToConstant: gradientHeight)
|
|
141
|
+
])
|
|
142
|
+
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
|
|
143
|
+
gradientLayer.endPoint = CGPoint(x: 0, y: 1)
|
|
144
|
+
} else {
|
|
145
|
+
gradientView.layer.addSublayer(gradientLayer)
|
|
146
|
+
NSLayoutConstraint.activate([
|
|
147
|
+
gradientView.bottomAnchor.constraint(equalTo: header.topAnchor),
|
|
148
|
+
gradientView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
149
|
+
gradientView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
150
|
+
gradientView.heightAnchor.constraint(equalToConstant: gradientHeight)
|
|
151
|
+
])
|
|
152
|
+
gradientLayer.startPoint = CGPoint(x: 0, y: 1)
|
|
153
|
+
gradientLayer.endPoint = CGPoint(x: 0, y: 0)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
gradientView.layoutIfNeeded()
|
|
157
|
+
gradientLayer.frame = gradientView.bounds
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// MARK: - Load URL
|
|
80
161
|
private func load() {
|
|
81
162
|
webView.load(URLRequest(url: url))
|
|
82
163
|
}
|
|
@@ -85,11 +166,9 @@ final class CustomWebViewController: UIViewController, UIGestureRecognizerDelega
|
|
|
85
166
|
dismiss(animated: true)
|
|
86
167
|
}
|
|
87
168
|
|
|
88
|
-
|
|
89
|
-
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
90
|
-
}
|
|
91
|
-
|
|
169
|
+
// MARK: - Toast
|
|
92
170
|
private var toastView: UIView?
|
|
171
|
+
private var lastBackPressedAt: Date?
|
|
93
172
|
|
|
94
173
|
private func showToast(_ message: String) {
|
|
95
174
|
toastView?.removeFromSuperview()
|
|
@@ -121,10 +200,7 @@ final class CustomWebViewController: UIViewController, UIGestureRecognizerDelega
|
|
|
121
200
|
label.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -14),
|
|
122
201
|
|
|
123
202
|
container.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
|
124
|
-
container.bottomAnchor.constraint(
|
|
125
|
-
equalTo: view.safeAreaLayoutGuide.bottomAnchor,
|
|
126
|
-
constant: -20
|
|
127
|
-
),
|
|
203
|
+
container.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
|
|
128
204
|
container.widthAnchor.constraint(lessThanOrEqualToConstant: 320)
|
|
129
205
|
])
|
|
130
206
|
|
|
@@ -140,23 +216,20 @@ final class CustomWebViewController: UIViewController, UIGestureRecognizerDelega
|
|
|
140
216
|
}
|
|
141
217
|
}
|
|
142
218
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
219
|
+
|
|
220
|
+
// MARK: - Back button
|
|
146
221
|
@objc private func backTapped() {
|
|
147
222
|
if webView.canGoBack {
|
|
148
|
-
|
|
149
|
-
|
|
223
|
+
webView.goBack()
|
|
224
|
+
return
|
|
150
225
|
}
|
|
151
|
-
|
|
226
|
+
|
|
152
227
|
let now = Date()
|
|
153
|
-
|
|
154
|
-
if let last = lastBackPressedAt,
|
|
155
|
-
now.timeIntervalSince(last) < 2 {
|
|
228
|
+
if let last = lastBackPressedAt, now.timeIntervalSince(last) < 2 {
|
|
156
229
|
dismiss(animated: true)
|
|
157
230
|
} else {
|
|
158
231
|
lastBackPressedAt = now
|
|
159
|
-
showToast(
|
|
232
|
+
showToast(closeWarningText)
|
|
160
233
|
}
|
|
161
234
|
}
|
|
162
235
|
}
|
|
@@ -16,7 +16,10 @@ public class CustomWebViewPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
16
16
|
|
|
17
17
|
@objc func open(_ call: CAPPluginCall) {
|
|
18
18
|
let urlString = call.getString("url") ?? ""
|
|
19
|
-
let closeButtonText = call.getString("closeButtonText")
|
|
19
|
+
let closeButtonText = call.getString("closeButtonText")
|
|
20
|
+
let closeWarningText = call.getString("closeWarningText")
|
|
21
|
+
let positionString = call.getString("toolbarPosition") ?? "top"
|
|
22
|
+
let position: ToolbarPosition = positionString == "bottom" ? .bottom : .top
|
|
20
23
|
guard let url = URL(string: urlString) else {
|
|
21
24
|
call.reject("Invalid URL")
|
|
22
25
|
return
|
|
@@ -24,7 +27,7 @@ public class CustomWebViewPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
24
27
|
|
|
25
28
|
|
|
26
29
|
DispatchQueue.main.async {
|
|
27
|
-
let vc = CustomWebViewController(url: url, closeButtonText: closeButtonText)
|
|
30
|
+
let vc = CustomWebViewController(url: url, closeButtonText: closeButtonText, closeWarningText: closeWarningText, toolbarPosition: position)
|
|
28
31
|
vc.modalPresentationStyle = .fullScreen
|
|
29
32
|
self.bridge?.viewController?.present(vc, animated: true)
|
|
30
33
|
self.webVC = vc
|