@jaeyeonee/capacitor-ios-webview 0.0.3 → 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.
@@ -3,7 +3,7 @@ require 'json'
3
3
  package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
4
 
5
5
  Pod::Spec.new do |s|
6
- s.name = 'CapacitorIosCustomWebView'
6
+ s.name = 'JaeyeoneeCapacitorIosWebview'
7
7
  s.version = package['version']
8
8
  s.summary = package['description']
9
9
  s.license = package['license']
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>",
@@ -2,6 +2,8 @@ export interface CustomWebViewPlugin {
2
2
  open(options: {
3
3
  url: string;
4
4
  closeButtonText?: string;
5
+ closeWarningText?: string;
6
+ toolbarPosition?: 'top' | 'bottom';
5
7
  }): Promise<void>;
6
8
  close(): Promise<void>;
7
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface CustomWebViewPlugin {\n open(options: { url: string, closeButtonText?: string }): Promise<void>;\n\n close(): Promise<void>;\n}\n"]}
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, UIGestureRecognizerDelegate, WKNavigationDelegate {
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
- init(url: URL, closeButtonText: String? = nil) {
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 ?? "Close"
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
- let header = UIView()
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
- close.setTitle(closeButtonText, for: .normal)
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.leadingAnchor.constraint(equalTo: back.trailingAnchor, constant: 4),
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
- private var lastBackPressedAt: Date?
145
-
219
+
220
+ // MARK: - Back button
146
221
  @objc private func backTapped() {
147
222
  if webView.canGoBack {
148
- webView.goBack()
149
- return
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
@@ -0,0 +1,6 @@
1
+ import Foundation
2
+
3
+ @objc public enum ToolbarPosition: Int {
4
+ case top
5
+ case bottom
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaeyeonee/capacitor-ios-webview",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Jaeyeonee / Capacitor IOS Webview",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",