@onekeyfe/react-native-native-sheet 3.0.129 → 3.0.131
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/NativeSheet.podspec +1 -0
- package/README.md +41 -8
- package/android/src/main/java/com/onekey/nativesheet/NativeSheetView.kt +610 -41
- package/ios/NativeSheetContainerView.swift +355 -46
- package/lib/module/NativeSheetHeight.js +43 -0
- package/lib/module/NativeSheetHeight.js.map +1 -0
- package/lib/module/NativeSheetRegistry.js +181 -0
- package/lib/module/NativeSheetRegistry.js.map +1 -0
- package/lib/module/index.js +180 -21
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/NativeSheetHeight.d.ts +20 -0
- package/lib/typescript/src/NativeSheetHeight.d.ts.map +1 -0
- package/lib/typescript/src/NativeSheetRegistry.d.ts +22 -0
- package/lib/typescript/src/NativeSheetRegistry.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +38 -12
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/NativeSheetHeight.ts +66 -0
- package/src/NativeSheetRegistry.ts +210 -0
- package/src/index.tsx +294 -20
|
@@ -1,6 +1,98 @@
|
|
|
1
1
|
import React
|
|
2
2
|
import UIKit
|
|
3
3
|
|
|
4
|
+
private enum NativeSheetQuickAnimation {
|
|
5
|
+
static func makeAnimator() -> UIViewPropertyAnimator {
|
|
6
|
+
let timing = UISpringTimingParameters(
|
|
7
|
+
mass: 0.1,
|
|
8
|
+
stiffness: 100,
|
|
9
|
+
damping: 20,
|
|
10
|
+
initialVelocity: .zero
|
|
11
|
+
)
|
|
12
|
+
return UIViewPropertyAnimator(duration: 0, timingParameters: timing)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static var duration: TimeInterval {
|
|
16
|
+
makeAnimator().duration
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
private final class NativeSheetTransitionAnimator: NSObject,
|
|
21
|
+
UIViewControllerAnimatedTransitioning {
|
|
22
|
+
private let presenting: Bool
|
|
23
|
+
private var animator: UIViewPropertyAnimator?
|
|
24
|
+
|
|
25
|
+
init(presenting: Bool) {
|
|
26
|
+
self.presenting = presenting
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func transitionDuration(
|
|
30
|
+
using transitionContext: UIViewControllerContextTransitioning?
|
|
31
|
+
) -> TimeInterval {
|
|
32
|
+
NativeSheetQuickAnimation.duration
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
|
|
36
|
+
let animator = interruptibleAnimator(using: transitionContext)
|
|
37
|
+
animator.startAnimation()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func interruptibleAnimator(
|
|
41
|
+
using transitionContext: UIViewControllerContextTransitioning
|
|
42
|
+
) -> UIViewImplicitlyAnimating {
|
|
43
|
+
if let animator {
|
|
44
|
+
return animator
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let key: UITransitionContextViewKey = presenting ? .to : .from
|
|
48
|
+
guard let sheetView = transitionContext.view(forKey: key) else {
|
|
49
|
+
transitionContext.completeTransition(false)
|
|
50
|
+
return NativeSheetQuickAnimation.makeAnimator()
|
|
51
|
+
}
|
|
52
|
+
let controllerKey: UITransitionContextViewControllerKey = presenting ? .to : .from
|
|
53
|
+
guard let sheetController = transitionContext.viewController(forKey: controllerKey)
|
|
54
|
+
as? NativeSheetViewController else {
|
|
55
|
+
transitionContext.completeTransition(false)
|
|
56
|
+
return NativeSheetQuickAnimation.makeAnimator()
|
|
57
|
+
}
|
|
58
|
+
let container = transitionContext.containerView
|
|
59
|
+
let finalFrame = presenting
|
|
60
|
+
? transitionContext.finalFrame(for: sheetController)
|
|
61
|
+
: sheetView.frame
|
|
62
|
+
let travel = max(container.bounds.maxY - finalFrame.minY, sheetView.bounds.height)
|
|
63
|
+
let offscreenTransform = CGAffineTransform(translationX: 0, y: travel)
|
|
64
|
+
|
|
65
|
+
if presenting {
|
|
66
|
+
sheetView.frame = finalFrame
|
|
67
|
+
sheetView.transform = offscreenTransform
|
|
68
|
+
sheetController.setDimmingAlpha(0)
|
|
69
|
+
if sheetView.superview == nil {
|
|
70
|
+
container.addSubview(sheetView)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let animator = NativeSheetQuickAnimation.makeAnimator()
|
|
75
|
+
animator.addAnimations {
|
|
76
|
+
sheetView.transform = self.presenting ? .identity : offscreenTransform
|
|
77
|
+
sheetController.setDimmingAlpha(self.presenting ? sheetController.resolvedDimAmount : 0)
|
|
78
|
+
}
|
|
79
|
+
animator.addCompletion { position in
|
|
80
|
+
let completed = position == .end && !transitionContext.transitionWasCancelled
|
|
81
|
+
if !completed {
|
|
82
|
+
sheetView.transform = self.presenting ? offscreenTransform : .identity
|
|
83
|
+
sheetController.setDimmingAlpha(self.presenting ? 0 : sheetController.resolvedDimAmount)
|
|
84
|
+
}
|
|
85
|
+
transitionContext.completeTransition(completed)
|
|
86
|
+
}
|
|
87
|
+
self.animator = animator
|
|
88
|
+
return animator
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func animationEnded(_ transitionCompleted: Bool) {
|
|
92
|
+
animator = nil
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
4
96
|
private final class WeakSheetHost {
|
|
5
97
|
weak var value: NativeSheetContainerView?
|
|
6
98
|
|
|
@@ -105,10 +197,14 @@ private final class NativeSheetPresentationCoordinator {
|
|
|
105
197
|
}
|
|
106
198
|
pending.removeFirst()
|
|
107
199
|
guard host.shouldPresent else {
|
|
200
|
+
host.finishFailedPresentation(
|
|
201
|
+
reason: host.securityBlocked ? "security" : (host.open ? "system" : "programmatic")
|
|
202
|
+
)
|
|
108
203
|
processPending()
|
|
109
204
|
return
|
|
110
205
|
}
|
|
111
206
|
guard let presenter = topViewController() else {
|
|
207
|
+
host.finishFailedPresentation(reason: "system")
|
|
112
208
|
processPending()
|
|
113
209
|
return
|
|
114
210
|
}
|
|
@@ -191,9 +287,12 @@ private final class NativeSheetPresentationCoordinator {
|
|
|
191
287
|
|
|
192
288
|
private final class NativeSheetViewController: UIViewController,
|
|
193
289
|
UIAdaptivePresentationControllerDelegate,
|
|
194
|
-
|
|
290
|
+
UIViewControllerTransitioningDelegate {
|
|
195
291
|
let host: NativeSheetContainerView
|
|
196
|
-
private let
|
|
292
|
+
private let detentIdentifier = UISheetPresentationController.Detent.Identifier(
|
|
293
|
+
"onekey.nativeSheet.fixed"
|
|
294
|
+
)
|
|
295
|
+
private var targetHeight: CGFloat
|
|
197
296
|
private let backgroundColorValue: UIColor
|
|
198
297
|
private let cornerRadiusValue: CGFloat
|
|
199
298
|
private let showHandleValue: Bool
|
|
@@ -201,6 +300,12 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
201
300
|
private let dimAmountValue: CGFloat
|
|
202
301
|
private var backdropTap: UITapGestureRecognizer?
|
|
203
302
|
private var dimmingView: UIView?
|
|
303
|
+
private var heightAnimator: UIViewPropertyAnimator?
|
|
304
|
+
private var shadowSuppressionDisplayLink: CADisplayLink?
|
|
305
|
+
|
|
306
|
+
fileprivate var resolvedDimAmount: CGFloat {
|
|
307
|
+
dimAmountValue
|
|
308
|
+
}
|
|
204
309
|
|
|
205
310
|
init(
|
|
206
311
|
host: NativeSheetContainerView,
|
|
@@ -212,7 +317,7 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
212
317
|
dimAmount: CGFloat
|
|
213
318
|
) {
|
|
214
319
|
self.host = host
|
|
215
|
-
self.
|
|
320
|
+
self.targetHeight = height
|
|
216
321
|
self.backgroundColorValue = backgroundColor
|
|
217
322
|
self.cornerRadiusValue = cornerRadius
|
|
218
323
|
self.showHandleValue = showHandle
|
|
@@ -220,6 +325,7 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
220
325
|
self.dimAmountValue = min(max(dimAmount, 0), 1)
|
|
221
326
|
super.init(nibName: nil, bundle: nil)
|
|
222
327
|
modalPresentationStyle = .pageSheet
|
|
328
|
+
transitioningDelegate = self
|
|
223
329
|
}
|
|
224
330
|
|
|
225
331
|
@available(*, unavailable)
|
|
@@ -235,6 +341,7 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
235
341
|
}
|
|
236
342
|
|
|
237
343
|
deinit {
|
|
344
|
+
shadowSuppressionDisplayLink?.invalidate()
|
|
238
345
|
dimmingView?.removeFromSuperview()
|
|
239
346
|
if isViewLoaded {
|
|
240
347
|
host.detachTouchHandler(from: view)
|
|
@@ -245,14 +352,13 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
245
352
|
super.viewDidLoad()
|
|
246
353
|
host.moveContent(to: view)
|
|
247
354
|
guard let sheet = sheetPresentationController else { return }
|
|
248
|
-
let identifier = UISheetPresentationController.Detent.Identifier("onekey.nativeSheet.fixed")
|
|
249
355
|
sheet.detents = [
|
|
250
|
-
.custom(identifier:
|
|
251
|
-
min(max(
|
|
356
|
+
.custom(identifier: detentIdentifier) { [weak self] context in
|
|
357
|
+
min(max(self?.targetHeight ?? 1, 1), context.maximumDetentValue)
|
|
252
358
|
},
|
|
253
359
|
]
|
|
254
|
-
sheet.selectedDetentIdentifier =
|
|
255
|
-
sheet.largestUndimmedDetentIdentifier =
|
|
360
|
+
sheet.selectedDetentIdentifier = detentIdentifier
|
|
361
|
+
sheet.largestUndimmedDetentIdentifier = detentIdentifier
|
|
256
362
|
sheet.prefersGrabberVisible = showHandleValue
|
|
257
363
|
sheet.preferredCornerRadius = cornerRadiusValue
|
|
258
364
|
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
|
|
@@ -262,29 +368,98 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
262
368
|
isModalInPresentation = !host.dismissOnPanDown
|
|
263
369
|
}
|
|
264
370
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
guard
|
|
269
|
-
|
|
270
|
-
let container = presentationController?.containerView else {
|
|
371
|
+
func updateHeight(_ height: CGFloat, animated: Bool) {
|
|
372
|
+
let nextHeight = max(height, 1)
|
|
373
|
+
guard abs(nextHeight - targetHeight) >= 0.5 else { return }
|
|
374
|
+
guard isViewLoaded, let sheet = sheetPresentationController else {
|
|
375
|
+
targetHeight = nextHeight
|
|
271
376
|
return
|
|
272
377
|
}
|
|
273
|
-
let
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
378
|
+
let changes = { [weak self, weak sheet] in
|
|
379
|
+
guard let self, let sheet else { return }
|
|
380
|
+
self.targetHeight = nextHeight
|
|
381
|
+
sheet.invalidateDetents()
|
|
382
|
+
sheet.selectedDetentIdentifier = self.detentIdentifier
|
|
383
|
+
sheet.containerView?.layoutIfNeeded()
|
|
384
|
+
}
|
|
385
|
+
guard animated else {
|
|
386
|
+
changes()
|
|
387
|
+
return
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if let heightAnimator {
|
|
391
|
+
heightAnimator.stopAnimation(false)
|
|
392
|
+
heightAnimator.finishAnimation(at: .current)
|
|
393
|
+
}
|
|
394
|
+
sheet.containerView?.layoutIfNeeded()
|
|
395
|
+
let animator = NativeSheetQuickAnimation.makeAnimator()
|
|
396
|
+
heightAnimator = animator
|
|
397
|
+
animator.addAnimations(changes)
|
|
398
|
+
animator.addCompletion { [weak self, weak animator] _ in
|
|
399
|
+
guard let self, self.heightAnimator === animator else { return }
|
|
400
|
+
self.heightAnimator = nil
|
|
401
|
+
}
|
|
402
|
+
animator.startAnimation()
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
func animationController(
|
|
406
|
+
forPresented presented: UIViewController,
|
|
407
|
+
presenting: UIViewController,
|
|
408
|
+
source: UIViewController
|
|
409
|
+
) -> UIViewControllerAnimatedTransitioning? {
|
|
410
|
+
NativeSheetTransitionAnimator(presenting: true)
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
func animationController(
|
|
414
|
+
forDismissed dismissed: UIViewController
|
|
415
|
+
) -> UIViewControllerAnimatedTransitioning? {
|
|
416
|
+
NativeSheetTransitionAnimator(presenting: false)
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
override func viewWillAppear(_ animated: Bool) {
|
|
420
|
+
super.viewWillAppear(animated)
|
|
421
|
+
installDimmingView()
|
|
422
|
+
installBackdropTap()
|
|
423
|
+
startSuppressingPresentationShadow()
|
|
424
|
+
setDimmingVisible(true, animated: animated)
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
override func viewDidAppear(_ animated: Bool) {
|
|
428
|
+
super.viewDidAppear(animated)
|
|
429
|
+
stopSuppressingPresentationShadow()
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
override func viewWillDisappear(_ animated: Bool) {
|
|
433
|
+
super.viewWillDisappear(animated)
|
|
434
|
+
stopSuppressingPresentationShadow()
|
|
435
|
+
setDimmingVisible(false, animated: animated)
|
|
278
436
|
}
|
|
279
437
|
|
|
280
438
|
override func viewDidDisappear(_ animated: Bool) {
|
|
281
439
|
super.viewDidDisappear(animated)
|
|
440
|
+
if let backdropTap {
|
|
441
|
+
dimmingView?.removeGestureRecognizer(backdropTap)
|
|
442
|
+
}
|
|
443
|
+
backdropTap = nil
|
|
282
444
|
dimmingView?.removeFromSuperview()
|
|
283
445
|
dimmingView = nil
|
|
284
446
|
}
|
|
285
447
|
|
|
448
|
+
private func installBackdropTap() {
|
|
449
|
+
guard dismissOnBackdropPressValue,
|
|
450
|
+
backdropTap == nil,
|
|
451
|
+
let dimmingView else {
|
|
452
|
+
return
|
|
453
|
+
}
|
|
454
|
+
let recognizer = UITapGestureRecognizer(target: self, action: #selector(handleBackdropTap(_:)))
|
|
455
|
+
recognizer.cancelsTouchesInView = true
|
|
456
|
+
dimmingView.addGestureRecognizer(recognizer)
|
|
457
|
+
backdropTap = recognizer
|
|
458
|
+
}
|
|
459
|
+
|
|
286
460
|
override func viewDidLayoutSubviews() {
|
|
287
461
|
super.viewDidLayoutSubviews()
|
|
462
|
+
removePresentationShadow()
|
|
288
463
|
host.layoutPresentedContent(in: view.bounds)
|
|
289
464
|
}
|
|
290
465
|
|
|
@@ -296,13 +471,6 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
296
471
|
NativeSheetPresentationCoordinator.shared.didDismissInteractively(host, reason: "pan")
|
|
297
472
|
}
|
|
298
473
|
|
|
299
|
-
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
|
|
300
|
-
guard let container = presentationController?.containerView else { return false }
|
|
301
|
-
let point = touch.location(in: container)
|
|
302
|
-
let sheetFrame = view.convert(view.bounds, to: container)
|
|
303
|
-
return !sheetFrame.contains(point)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
474
|
@objc private func handleBackdropTap(_ recognizer: UITapGestureRecognizer) {
|
|
307
475
|
guard recognizer.state == .ended else { return }
|
|
308
476
|
NativeSheetPresentationCoordinator.shared.dismiss(host, reason: "backdrop", animated: true)
|
|
@@ -315,11 +483,135 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
315
483
|
}
|
|
316
484
|
let dimmingView = UIView(frame: container.bounds)
|
|
317
485
|
dimmingView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
318
|
-
dimmingView.backgroundColor =
|
|
319
|
-
dimmingView.
|
|
486
|
+
dimmingView.backgroundColor = .black
|
|
487
|
+
dimmingView.alpha = 0
|
|
488
|
+
// Always consume backdrop touches. When dismissal is disabled there is no
|
|
489
|
+
// recognizer, but taps still cannot reach the sheet below or the app page.
|
|
490
|
+
dimmingView.isUserInteractionEnabled = true
|
|
320
491
|
container.insertSubview(dimmingView, at: 0)
|
|
321
492
|
self.dimmingView = dimmingView
|
|
322
493
|
}
|
|
494
|
+
|
|
495
|
+
fileprivate func setDimmingAlpha(_ alpha: CGFloat) {
|
|
496
|
+
dimmingView?.alpha = alpha
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
private func removePresentationShadow() {
|
|
500
|
+
guard let container = presentationController?.containerView else { return }
|
|
501
|
+
var ancestor = view.superview
|
|
502
|
+
while let current = ancestor, current !== container {
|
|
503
|
+
clearShadow(on: current)
|
|
504
|
+
ancestor = current.superview
|
|
505
|
+
}
|
|
506
|
+
removeDropShadowViews(in: container)
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
private func removeDropShadowViews(in candidate: UIView) {
|
|
510
|
+
guard candidate !== view else { return }
|
|
511
|
+
let className = NSStringFromClass(type(of: candidate))
|
|
512
|
+
guard className.hasPrefix("UI") || className.hasPrefix("_UI") else { return }
|
|
513
|
+
if className.contains("DropShadowView") {
|
|
514
|
+
clearShadow(on: candidate)
|
|
515
|
+
}
|
|
516
|
+
for subview in candidate.subviews {
|
|
517
|
+
removeDropShadowViews(in: subview)
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
private func clearShadow(on shadowView: UIView) {
|
|
522
|
+
CATransaction.begin()
|
|
523
|
+
CATransaction.setDisableActions(true)
|
|
524
|
+
shadowView.layer.shadowOpacity = 0
|
|
525
|
+
shadowView.layer.shadowRadius = 0
|
|
526
|
+
shadowView.layer.shadowColor = UIColor.clear.cgColor
|
|
527
|
+
shadowView.layer.shadowPath = nil
|
|
528
|
+
CATransaction.commit()
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
private func startSuppressingPresentationShadow() {
|
|
532
|
+
shadowSuppressionDisplayLink?.invalidate()
|
|
533
|
+
removePresentationShadow()
|
|
534
|
+
let displayLink = CADisplayLink(
|
|
535
|
+
target: self,
|
|
536
|
+
selector: #selector(suppressPresentationShadowForCurrentFrame)
|
|
537
|
+
)
|
|
538
|
+
displayLink.add(to: .main, forMode: .common)
|
|
539
|
+
shadowSuppressionDisplayLink = displayLink
|
|
540
|
+
|
|
541
|
+
if let transitionCoordinator {
|
|
542
|
+
transitionCoordinator.animate(alongsideTransition: nil) { [weak self] _ in
|
|
543
|
+
self?.stopSuppressingPresentationShadow()
|
|
544
|
+
}
|
|
545
|
+
} else {
|
|
546
|
+
DispatchQueue.main.asyncAfter(
|
|
547
|
+
deadline: .now() + NativeSheetQuickAnimation.duration
|
|
548
|
+
) { [weak self] in
|
|
549
|
+
self?.stopSuppressingPresentationShadow()
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
private func stopSuppressingPresentationShadow() {
|
|
555
|
+
shadowSuppressionDisplayLink?.invalidate()
|
|
556
|
+
shadowSuppressionDisplayLink = nil
|
|
557
|
+
removePresentationShadow()
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
@objc private func suppressPresentationShadowForCurrentFrame() {
|
|
561
|
+
removePresentationShadow()
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
private func setDimmingVisible(_ visible: Bool, animated: Bool) {
|
|
565
|
+
guard let dimmingView else { return }
|
|
566
|
+
let targetAlpha = visible ? dimAmountValue : 0
|
|
567
|
+
let animations = {
|
|
568
|
+
dimmingView.alpha = targetAlpha
|
|
569
|
+
}
|
|
570
|
+
guard animated else {
|
|
571
|
+
animations()
|
|
572
|
+
return
|
|
573
|
+
}
|
|
574
|
+
if let transitionCoordinator {
|
|
575
|
+
transitionCoordinator.animate(alongsideTransition: { _ in
|
|
576
|
+
animations()
|
|
577
|
+
}, completion: { context in
|
|
578
|
+
dimmingView.alpha = context.isCancelled
|
|
579
|
+
? (visible ? 0 : self.dimAmountValue)
|
|
580
|
+
: targetAlpha
|
|
581
|
+
})
|
|
582
|
+
} else {
|
|
583
|
+
UIView.animate(
|
|
584
|
+
withDuration: 0.25,
|
|
585
|
+
delay: 0,
|
|
586
|
+
options: [.beginFromCurrentState, .curveEaseInOut],
|
|
587
|
+
animations: animations
|
|
588
|
+
)
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
private final class NativeSheetContentWrapperView: UIView {
|
|
594
|
+
private weak var contentChild: UIView?
|
|
595
|
+
|
|
596
|
+
func setContentChild(_ child: UIView?) {
|
|
597
|
+
if contentChild !== child {
|
|
598
|
+
contentChild?.autoresizingMask = []
|
|
599
|
+
contentChild?.removeFromSuperview()
|
|
600
|
+
}
|
|
601
|
+
contentChild = child
|
|
602
|
+
guard let child else { return }
|
|
603
|
+
child.autoresizingMask = []
|
|
604
|
+
if child.superview !== self {
|
|
605
|
+
child.removeFromSuperview()
|
|
606
|
+
addSubview(child)
|
|
607
|
+
}
|
|
608
|
+
setNeedsLayout()
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
override func layoutSubviews() {
|
|
612
|
+
super.layoutSubviews()
|
|
613
|
+
contentChild?.frame = bounds
|
|
614
|
+
}
|
|
323
615
|
}
|
|
324
616
|
|
|
325
617
|
@objc final class NativeSheetContainerView: UIView {
|
|
@@ -343,6 +635,11 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
343
635
|
}
|
|
344
636
|
|
|
345
637
|
private weak var contentChild: UIView?
|
|
638
|
+
private let contentWrapperView: NativeSheetContentWrapperView = {
|
|
639
|
+
let view = NativeSheetContentWrapperView()
|
|
640
|
+
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
641
|
+
return view
|
|
642
|
+
}()
|
|
346
643
|
private var committedOpen = false
|
|
347
644
|
private var dismissedForCurrentOpen = false
|
|
348
645
|
private var dismissNotified = false
|
|
@@ -359,34 +656,34 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
359
656
|
override func layoutSubviews() {
|
|
360
657
|
super.layoutSubviews()
|
|
361
658
|
if presentedController == nil {
|
|
362
|
-
|
|
659
|
+
contentWrapperView.frame = bounds
|
|
363
660
|
}
|
|
364
661
|
}
|
|
365
662
|
|
|
366
663
|
@objc func insertChild(_ child: UIView, atIndex index: Int) {
|
|
367
|
-
|
|
368
|
-
contentChild?.removeFromSuperview()
|
|
369
|
-
}
|
|
664
|
+
contentWrapperView.setContentChild(child)
|
|
370
665
|
contentChild = child
|
|
371
666
|
if let controller = presentedController {
|
|
372
667
|
moveContent(to: controller.view)
|
|
373
668
|
} else {
|
|
374
|
-
|
|
375
|
-
addSubview(child)
|
|
376
|
-
child.frame = bounds
|
|
377
|
-
child.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
669
|
+
moveContent(to: self)
|
|
378
670
|
}
|
|
379
671
|
}
|
|
380
672
|
|
|
381
673
|
@objc func removeChild(_ child: UIView) {
|
|
382
674
|
guard contentChild === child else { return }
|
|
383
|
-
|
|
675
|
+
contentWrapperView.setContentChild(nil)
|
|
676
|
+
contentWrapperView.removeFromSuperview()
|
|
677
|
+
child.autoresizingMask = []
|
|
384
678
|
contentChild = nil
|
|
385
679
|
}
|
|
386
680
|
|
|
387
681
|
@objc func commitConfiguration() {
|
|
388
682
|
let openChanged = committedOpen != open
|
|
389
683
|
committedOpen = open
|
|
684
|
+
if openChanged && open {
|
|
685
|
+
dismissNotified = false
|
|
686
|
+
}
|
|
390
687
|
if !open {
|
|
391
688
|
dismissedForCurrentOpen = false
|
|
392
689
|
}
|
|
@@ -400,6 +697,10 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
400
697
|
(openChanged || presentedController == nil),
|
|
401
698
|
!dismissedForCurrentOpen {
|
|
402
699
|
NativeSheetPresentationCoordinator.shared.present(self)
|
|
700
|
+
} else if let controller = presentedController, !dismissedForCurrentOpen {
|
|
701
|
+
let shouldAnimate = controller.presentingViewController != nil
|
|
702
|
+
&& !controller.isBeingPresented
|
|
703
|
+
controller.updateHeight(sheetHeight, animated: shouldAnimate)
|
|
403
704
|
}
|
|
404
705
|
}
|
|
405
706
|
|
|
@@ -429,12 +730,17 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
429
730
|
onPresented?(["height": min(sheetHeight, controller.view.bounds.height)])
|
|
430
731
|
}
|
|
431
732
|
|
|
733
|
+
fileprivate func finishFailedPresentation(reason: String) {
|
|
734
|
+
dismissedForCurrentOpen = committedOpen
|
|
735
|
+
guard !dismissNotified else { return }
|
|
736
|
+
dismissNotified = true
|
|
737
|
+
onDismiss?(["reason": reason])
|
|
738
|
+
}
|
|
739
|
+
|
|
432
740
|
fileprivate func finishDismiss(reason: String) {
|
|
433
741
|
if let child = contentChild {
|
|
434
|
-
child.
|
|
435
|
-
|
|
436
|
-
child.frame = bounds
|
|
437
|
-
child.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
742
|
+
child.autoresizingMask = []
|
|
743
|
+
moveContent(to: self)
|
|
438
744
|
}
|
|
439
745
|
let hadController = presentedController != nil
|
|
440
746
|
presentedController = nil
|
|
@@ -447,14 +753,17 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
447
753
|
|
|
448
754
|
fileprivate func moveContent(to parent: UIView) {
|
|
449
755
|
guard let child = contentChild else { return }
|
|
450
|
-
child.
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
756
|
+
child.autoresizingMask = []
|
|
757
|
+
contentWrapperView.setContentChild(child)
|
|
758
|
+
if contentWrapperView.superview !== parent {
|
|
759
|
+
contentWrapperView.removeFromSuperview()
|
|
760
|
+
parent.addSubview(contentWrapperView)
|
|
761
|
+
}
|
|
762
|
+
contentWrapperView.frame = parent.bounds
|
|
454
763
|
}
|
|
455
764
|
|
|
456
765
|
fileprivate func layoutPresentedContent(in bounds: CGRect) {
|
|
457
|
-
|
|
766
|
+
contentWrapperView.frame = bounds
|
|
458
767
|
}
|
|
459
768
|
|
|
460
769
|
fileprivate func attachTouchHandler(to view: UIView) {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
export function resolveNativeSheetLayoutConstraints({
|
|
4
|
+
lockedHeight,
|
|
5
|
+
maxHeight,
|
|
6
|
+
shouldAutoMeasure
|
|
7
|
+
}) {
|
|
8
|
+
if (shouldAutoMeasure) {
|
|
9
|
+
return {
|
|
10
|
+
hostMaxHeight: maxHeight,
|
|
11
|
+
shouldFillHost: false
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
if (lockedHeight !== undefined) {
|
|
15
|
+
return {
|
|
16
|
+
hostHeight: lockedHeight,
|
|
17
|
+
shouldFillHost: true
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
hostMaxHeight: maxHeight,
|
|
22
|
+
shouldFillHost: false
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function resolveNativeSheetHeight({
|
|
26
|
+
currentHeight,
|
|
27
|
+
explicitHeight,
|
|
28
|
+
measuredHeight,
|
|
29
|
+
maxHeight,
|
|
30
|
+
shouldAutoMeasure
|
|
31
|
+
}) {
|
|
32
|
+
if (explicitHeight !== undefined && explicitHeight > 0) {
|
|
33
|
+
return Math.min(explicitHeight, maxHeight);
|
|
34
|
+
}
|
|
35
|
+
if (explicitHeight === undefined && shouldAutoMeasure && measuredHeight !== undefined && measuredHeight > 0) {
|
|
36
|
+
return Math.min(measuredHeight, maxHeight);
|
|
37
|
+
}
|
|
38
|
+
if (currentHeight !== undefined && currentHeight > maxHeight) {
|
|
39
|
+
return maxHeight;
|
|
40
|
+
}
|
|
41
|
+
return currentHeight;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=NativeSheetHeight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["resolveNativeSheetLayoutConstraints","lockedHeight","maxHeight","shouldAutoMeasure","hostMaxHeight","shouldFillHost","undefined","hostHeight","resolveNativeSheetHeight","currentHeight","explicitHeight","measuredHeight","Math","min"],"sourceRoot":"../../src","sources":["NativeSheetHeight.ts"],"mappings":";;AAoBA,OAAO,SAASA,mCAAmCA,CAAC;EAClDC,YAAY;EACZC,SAAS;EACTC;AAC0C,CAAC,EAAgC;EAC3E,IAAIA,iBAAiB,EAAE;IACrB,OAAO;MACLC,aAAa,EAAEF,SAAS;MACxBG,cAAc,EAAE;IAClB,CAAC;EACH;EACA,IAAIJ,YAAY,KAAKK,SAAS,EAAE;IAC9B,OAAO;MACLC,UAAU,EAAEN,YAAY;MACxBI,cAAc,EAAE;IAClB,CAAC;EACH;EACA,OAAO;IACLD,aAAa,EAAEF,SAAS;IACxBG,cAAc,EAAE;EAClB,CAAC;AACH;AAEA,OAAO,SAASG,wBAAwBA,CAAC;EACvCC,aAAa;EACbC,cAAc;EACdC,cAAc;EACdT,SAAS;EACTC;AAC+B,CAAC,EAAsB;EACtD,IAAIO,cAAc,KAAKJ,SAAS,IAAII,cAAc,GAAG,CAAC,EAAE;IACtD,OAAOE,IAAI,CAACC,GAAG,CAACH,cAAc,EAAER,SAAS,CAAC;EAC5C;EACA,IACEQ,cAAc,KAAKJ,SAAS,IAC5BH,iBAAiB,IACjBQ,cAAc,KAAKL,SAAS,IAC5BK,cAAc,GAAG,CAAC,EAClB;IACA,OAAOC,IAAI,CAACC,GAAG,CAACF,cAAc,EAAET,SAAS,CAAC;EAC5C;EACA,IAAIO,aAAa,KAAKH,SAAS,IAAIG,aAAa,GAAGP,SAAS,EAAE;IAC5D,OAAOA,SAAS;EAClB;EACA,OAAOO,aAAa;AACtB","ignoreList":[]}
|