@onekeyfe/react-native-native-sheet 3.0.128 → 3.0.130
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 +41 -8
- package/android/src/main/java/com/onekey/nativesheet/NativeSheetView.kt +610 -41
- package/ios/NativeSheetContainerView.swift +355 -45
- package/lib/module/NativeSheetHeight.js +43 -0
- package/lib/module/NativeSheetHeight.js.map +1 -0
- package/lib/module/NativeSheetRegistry.js +176 -0
- package/lib/module/NativeSheetRegistry.js.map +1 -0
- package/lib/module/index.js +180 -20
- 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 +202 -0
- package/src/index.tsx +294 -19
|
@@ -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,12 +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
|
-
return !view.frame.contains(point)
|
|
303
|
-
}
|
|
304
|
-
|
|
305
474
|
@objc private func handleBackdropTap(_ recognizer: UITapGestureRecognizer) {
|
|
306
475
|
guard recognizer.state == .ended else { return }
|
|
307
476
|
NativeSheetPresentationCoordinator.shared.dismiss(host, reason: "backdrop", animated: true)
|
|
@@ -314,11 +483,135 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
314
483
|
}
|
|
315
484
|
let dimmingView = UIView(frame: container.bounds)
|
|
316
485
|
dimmingView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
317
|
-
dimmingView.backgroundColor =
|
|
318
|
-
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
|
|
319
491
|
container.insertSubview(dimmingView, at: 0)
|
|
320
492
|
self.dimmingView = dimmingView
|
|
321
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
|
+
}
|
|
322
615
|
}
|
|
323
616
|
|
|
324
617
|
@objc final class NativeSheetContainerView: UIView {
|
|
@@ -342,6 +635,11 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
342
635
|
}
|
|
343
636
|
|
|
344
637
|
private weak var contentChild: UIView?
|
|
638
|
+
private let contentWrapperView: NativeSheetContentWrapperView = {
|
|
639
|
+
let view = NativeSheetContentWrapperView()
|
|
640
|
+
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
641
|
+
return view
|
|
642
|
+
}()
|
|
345
643
|
private var committedOpen = false
|
|
346
644
|
private var dismissedForCurrentOpen = false
|
|
347
645
|
private var dismissNotified = false
|
|
@@ -358,34 +656,34 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
358
656
|
override func layoutSubviews() {
|
|
359
657
|
super.layoutSubviews()
|
|
360
658
|
if presentedController == nil {
|
|
361
|
-
|
|
659
|
+
contentWrapperView.frame = bounds
|
|
362
660
|
}
|
|
363
661
|
}
|
|
364
662
|
|
|
365
663
|
@objc func insertChild(_ child: UIView, atIndex index: Int) {
|
|
366
|
-
|
|
367
|
-
contentChild?.removeFromSuperview()
|
|
368
|
-
}
|
|
664
|
+
contentWrapperView.setContentChild(child)
|
|
369
665
|
contentChild = child
|
|
370
666
|
if let controller = presentedController {
|
|
371
667
|
moveContent(to: controller.view)
|
|
372
668
|
} else {
|
|
373
|
-
|
|
374
|
-
addSubview(child)
|
|
375
|
-
child.frame = bounds
|
|
376
|
-
child.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
669
|
+
moveContent(to: self)
|
|
377
670
|
}
|
|
378
671
|
}
|
|
379
672
|
|
|
380
673
|
@objc func removeChild(_ child: UIView) {
|
|
381
674
|
guard contentChild === child else { return }
|
|
382
|
-
|
|
675
|
+
contentWrapperView.setContentChild(nil)
|
|
676
|
+
contentWrapperView.removeFromSuperview()
|
|
677
|
+
child.autoresizingMask = []
|
|
383
678
|
contentChild = nil
|
|
384
679
|
}
|
|
385
680
|
|
|
386
681
|
@objc func commitConfiguration() {
|
|
387
682
|
let openChanged = committedOpen != open
|
|
388
683
|
committedOpen = open
|
|
684
|
+
if openChanged && open {
|
|
685
|
+
dismissNotified = false
|
|
686
|
+
}
|
|
389
687
|
if !open {
|
|
390
688
|
dismissedForCurrentOpen = false
|
|
391
689
|
}
|
|
@@ -399,6 +697,10 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
399
697
|
(openChanged || presentedController == nil),
|
|
400
698
|
!dismissedForCurrentOpen {
|
|
401
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)
|
|
402
704
|
}
|
|
403
705
|
}
|
|
404
706
|
|
|
@@ -428,12 +730,17 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
428
730
|
onPresented?(["height": min(sheetHeight, controller.view.bounds.height)])
|
|
429
731
|
}
|
|
430
732
|
|
|
733
|
+
fileprivate func finishFailedPresentation(reason: String) {
|
|
734
|
+
dismissedForCurrentOpen = committedOpen
|
|
735
|
+
guard !dismissNotified else { return }
|
|
736
|
+
dismissNotified = true
|
|
737
|
+
onDismiss?(["reason": reason])
|
|
738
|
+
}
|
|
739
|
+
|
|
431
740
|
fileprivate func finishDismiss(reason: String) {
|
|
432
741
|
if let child = contentChild {
|
|
433
|
-
child.
|
|
434
|
-
|
|
435
|
-
child.frame = bounds
|
|
436
|
-
child.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
742
|
+
child.autoresizingMask = []
|
|
743
|
+
moveContent(to: self)
|
|
437
744
|
}
|
|
438
745
|
let hadController = presentedController != nil
|
|
439
746
|
presentedController = nil
|
|
@@ -446,14 +753,17 @@ private final class NativeSheetViewController: UIViewController,
|
|
|
446
753
|
|
|
447
754
|
fileprivate func moveContent(to parent: UIView) {
|
|
448
755
|
guard let child = contentChild else { return }
|
|
449
|
-
child.
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
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
|
|
453
763
|
}
|
|
454
764
|
|
|
455
765
|
fileprivate func layoutPresentedContent(in bounds: CGRect) {
|
|
456
|
-
|
|
766
|
+
contentWrapperView.frame = bounds
|
|
457
767
|
}
|
|
458
768
|
|
|
459
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":[]}
|