@capgo/capacitor-native-navigation 8.0.16 → 8.0.17
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.
|
@@ -48,6 +48,7 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
|
|
|
48
48
|
private weak var originalWebViewSuperview: UIView?
|
|
49
49
|
private var originalWebViewIndex: Int?
|
|
50
50
|
private var originalWebViewAutoresizingMask: UIView.AutoresizingMask?
|
|
51
|
+
private var liftedWebViewOverlays: [NativeNavigationWeakView] = []
|
|
51
52
|
private var isWebViewHostedInSystemTabController = false
|
|
52
53
|
private var navbarHeight: CGFloat = 44
|
|
53
54
|
private var tabbarHeight: CGFloat = 64
|
|
@@ -568,6 +569,7 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
|
|
|
568
569
|
|
|
569
570
|
self.tabBarController = controller
|
|
570
571
|
self.tabBar = controller.tabBar
|
|
572
|
+
liftWebViewOverlaysAboveSystemTabs()
|
|
571
573
|
hostWebViewInSelectedSystemTab()
|
|
572
574
|
return controller.tabBar
|
|
573
575
|
}
|
|
@@ -605,6 +607,7 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
|
|
|
605
607
|
originalWebViewSuperview = container
|
|
606
608
|
originalWebViewIndex = 0
|
|
607
609
|
originalWebViewAutoresizingMask = webView.autoresizingMask
|
|
610
|
+
liftWebViewOverlaysAboveSystemTabs()
|
|
608
611
|
return container
|
|
609
612
|
}
|
|
610
613
|
|
|
@@ -688,6 +691,7 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
|
|
|
688
691
|
tabBarController?.view.isHidden = false
|
|
689
692
|
if usesSystemLiquidGlass {
|
|
690
693
|
setSystemTabBarHidden(false)
|
|
694
|
+
liftWebViewOverlaysAboveSystemTabs()
|
|
691
695
|
hostWebViewInSelectedSystemTab()
|
|
692
696
|
} else {
|
|
693
697
|
tabBar.isHidden = false
|
|
@@ -752,6 +756,7 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
|
|
|
752
756
|
return
|
|
753
757
|
}
|
|
754
758
|
|
|
759
|
+
liftWebViewOverlaysAboveSystemTabs()
|
|
755
760
|
captureOriginalWebViewPlacementIfNeeded(webView)
|
|
756
761
|
clearHostedWebViews(matching: webView, except: selectedController, preservingSnapshots: true)
|
|
757
762
|
guard selectedController.host(webView: webView) else {
|
|
@@ -760,6 +765,34 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
|
|
|
760
765
|
}
|
|
761
766
|
clearHostedWebViews(matching: webView, except: selectedController)
|
|
762
767
|
isWebViewHostedInSystemTabController = true
|
|
768
|
+
bringLiftedWebViewOverlaysToFront()
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
private func liftWebViewOverlaysAboveSystemTabs() {
|
|
772
|
+
guard usesSystemLiquidGlass,
|
|
773
|
+
let webView = webView,
|
|
774
|
+
let container = systemTabRootContainer else {
|
|
775
|
+
return
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
nativeNavigationLiftWebViewOverlaySubviews(
|
|
779
|
+
from: webView,
|
|
780
|
+
to: container,
|
|
781
|
+
tracking: &liftedWebViewOverlays,
|
|
782
|
+
excluding: [navContainer, tabContainer, tabBarController?.view]
|
|
783
|
+
)
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
private func bringLiftedWebViewOverlaysToFront() {
|
|
787
|
+
guard let container = systemTabRootContainer else {
|
|
788
|
+
return
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
liftedWebViewOverlays = liftedWebViewOverlays.filter { $0.value != nil }
|
|
792
|
+
liftedWebViewOverlays
|
|
793
|
+
.compactMap(\.value)
|
|
794
|
+
.filter { $0.superview === container }
|
|
795
|
+
.forEach { container.bringSubviewToFront($0) }
|
|
763
796
|
}
|
|
764
797
|
|
|
765
798
|
private func restoreWebViewFromSystemTabController() {
|
|
@@ -1224,6 +1257,7 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
|
|
|
1224
1257
|
if let navContainer = navContainer {
|
|
1225
1258
|
bridge?.viewController?.view.bringSubviewToFront(navContainer)
|
|
1226
1259
|
}
|
|
1260
|
+
bringLiftedWebViewOverlaysToFront()
|
|
1227
1261
|
return
|
|
1228
1262
|
}
|
|
1229
1263
|
|
|
@@ -1449,6 +1483,65 @@ private final class NativeNavigationBar: UINavigationBar {
|
|
|
1449
1483
|
}
|
|
1450
1484
|
}
|
|
1451
1485
|
|
|
1486
|
+
final class NativeNavigationWeakView {
|
|
1487
|
+
weak var value: UIView?
|
|
1488
|
+
|
|
1489
|
+
init(_ value: UIView) {
|
|
1490
|
+
self.value = value
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
func nativeNavigationLiftWebViewOverlaySubviews(
|
|
1495
|
+
from webView: UIView,
|
|
1496
|
+
to container: UIView,
|
|
1497
|
+
tracking liftedOverlays: inout [NativeNavigationWeakView],
|
|
1498
|
+
excluding excludedViews: [UIView?] = []
|
|
1499
|
+
) {
|
|
1500
|
+
webView.subviews
|
|
1501
|
+
.filter { nativeNavigationShouldLiftWebViewOverlay($0, excluding: excludedViews) }
|
|
1502
|
+
.forEach { overlay in
|
|
1503
|
+
let frame = overlay.convert(overlay.bounds, to: container)
|
|
1504
|
+
let hadParentConstraints = nativeNavigationDeactivateParentConstraints(in: webView, involving: overlay)
|
|
1505
|
+
overlay.removeFromSuperview()
|
|
1506
|
+
overlay.frame = frame
|
|
1507
|
+
if hadParentConstraints {
|
|
1508
|
+
overlay.translatesAutoresizingMaskIntoConstraints = true
|
|
1509
|
+
}
|
|
1510
|
+
overlay.autoresizingMask = overlay.autoresizingMask.isEmpty
|
|
1511
|
+
? [.flexibleWidth, .flexibleHeight]
|
|
1512
|
+
: overlay.autoresizingMask
|
|
1513
|
+
container.addSubview(overlay)
|
|
1514
|
+
liftedOverlays.append(NativeNavigationWeakView(overlay))
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
liftedOverlays = liftedOverlays.filter { $0.value != nil }
|
|
1518
|
+
liftedOverlays
|
|
1519
|
+
.compactMap(\.value)
|
|
1520
|
+
.filter { $0.superview === container }
|
|
1521
|
+
.forEach { container.bringSubviewToFront($0) }
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
func nativeNavigationShouldLiftWebViewOverlay(_ view: UIView, excluding excludedViews: [UIView?] = []) -> Bool {
|
|
1525
|
+
if excludedViews.contains(where: { $0 === view }) {
|
|
1526
|
+
return false
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
if view is UIScrollView {
|
|
1530
|
+
return false
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
let className = NSStringFromClass(type(of: view))
|
|
1534
|
+
return !className.contains("WK")
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
private func nativeNavigationDeactivateParentConstraints(in parent: UIView, involving view: UIView) -> Bool {
|
|
1538
|
+
let constraints = parent.constraints.filter { constraint in
|
|
1539
|
+
constraint.firstItem === view || constraint.secondItem === view
|
|
1540
|
+
}
|
|
1541
|
+
NSLayoutConstraint.deactivate(constraints)
|
|
1542
|
+
return !constraints.isEmpty
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1452
1545
|
final class NativeNavigationTabController: UITabBarController {
|
|
1453
1546
|
override func viewDidLoad() {
|
|
1454
1547
|
super.viewDidLoad()
|
|
@@ -51,6 +51,33 @@ class NativeNavigationTests: XCTestCase {
|
|
|
51
51
|
XCTAssertTrue(firstController.view.subviews.first === webView)
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
func testLiftWebViewOverlaySubviewsMovesSplashOverlayAboveContainerContent() {
|
|
55
|
+
let webView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 480))
|
|
56
|
+
let container = UIView(frame: webView.frame)
|
|
57
|
+
let tabControllerView = UIView(frame: webView.frame)
|
|
58
|
+
let scrollView = UIScrollView(frame: webView.bounds)
|
|
59
|
+
let splashOverlay = UIView(frame: webView.bounds)
|
|
60
|
+
var liftedOverlays: [NativeNavigationWeakView] = []
|
|
61
|
+
|
|
62
|
+
container.addSubview(webView)
|
|
63
|
+
container.addSubview(tabControllerView)
|
|
64
|
+
webView.addSubview(scrollView)
|
|
65
|
+
webView.addSubview(splashOverlay)
|
|
66
|
+
|
|
67
|
+
nativeNavigationLiftWebViewOverlaySubviews(
|
|
68
|
+
from: webView,
|
|
69
|
+
to: container,
|
|
70
|
+
tracking: &liftedOverlays,
|
|
71
|
+
excluding: [tabControllerView]
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
XCTAssertEqual(scrollView.superview, webView)
|
|
75
|
+
XCTAssertEqual(splashOverlay.superview, container)
|
|
76
|
+
XCTAssertTrue(container.subviews.last === splashOverlay)
|
|
77
|
+
XCTAssertEqual(liftedOverlays.count, 1)
|
|
78
|
+
XCTAssertTrue(liftedOverlays.first?.value === splashOverlay)
|
|
79
|
+
}
|
|
80
|
+
|
|
54
81
|
func testTabContentControllerRejectsLayerCycle() {
|
|
55
82
|
let webView = UIView()
|
|
56
83
|
let controller = NativeNavigationTabContentController()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/capacitor-native-navigation",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.17",
|
|
4
4
|
"description": "Capacitor plugin for native navbar, tabbar, and route transition chrome over a WebView.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|