@capgo/capacitor-native-navigation 8.0.14 → 8.0.15-beta.pr12.18.1

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 = 'CapgoNativeNavigation'
6
+ s.name = 'CapgoCapacitorNativeNavigation'
7
7
  s.version = package['version']
8
8
  s.summary = package['description']
9
9
  s.license = package['license']
package/Package.swift CHANGED
@@ -2,11 +2,11 @@
2
2
  import PackageDescription
3
3
 
4
4
  let package = Package(
5
- name: "CapgoNativeNavigation",
5
+ name: "CapgoCapacitorNativeNavigation",
6
6
  platforms: [.iOS(.v15)],
7
7
  products: [
8
8
  .library(
9
- name: "CapgoNativeNavigation",
9
+ name: "CapgoCapacitorNativeNavigation",
10
10
  targets: ["NativeNavigationPlugin"])
11
11
  ],
12
12
  dependencies: [
@@ -44,6 +44,7 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
44
44
  private var tabBar: UITabBar?
45
45
  private var tabBarController: NativeNavigationTabController?
46
46
  private var tabViewControllers: [UIViewController] = []
47
+ private weak var systemTabRootContainer: UIView?
47
48
  private weak var originalWebViewSuperview: UIView?
48
49
  private var originalWebViewIndex: Int?
49
50
  private var originalWebViewAutoresizingMask: UIView.AutoresizingMask?
@@ -552,8 +553,9 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
552
553
  controller.view.isHidden = !tabbarVisible
553
554
 
554
555
  if let parent = bridge?.viewController {
556
+ let containerView = systemTabHostingContainerView(in: parent)
555
557
  parent.addChild(controller)
556
- insertSystemTabControllerView(controller.view, in: parent.view)
558
+ insertSystemTabControllerView(controller.view, in: containerView)
557
559
  controller.didMove(toParent: parent)
558
560
  }
559
561
 
@@ -563,6 +565,49 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
563
565
  return controller.tabBar
564
566
  }
565
567
 
568
+ private func systemTabHostingContainerView(in parent: UIViewController) -> UIView {
569
+ if let systemTabRootContainer = systemTabRootContainer {
570
+ return systemTabRootContainer
571
+ }
572
+
573
+ guard let webView = webView,
574
+ parent.view === webView else {
575
+ return parent.view
576
+ }
577
+
578
+ let previousSuperview = webView.superview
579
+ let previousIndex = previousSuperview?.subviews.firstIndex(of: webView)
580
+ let previousFrame = webView.frame
581
+ let previousAutoresizingMask = webView.autoresizingMask
582
+ let container = UIView(frame: previousFrame)
583
+ container.backgroundColor = .clear
584
+ container.isOpaque = false
585
+ container.autoresizingMask = previousAutoresizingMask.isEmpty ? [.flexibleWidth, .flexibleHeight] : previousAutoresizingMask
586
+
587
+ if let previousSuperview = previousSuperview {
588
+ previousSuperview.insertSubview(container, at: min(previousIndex ?? previousSuperview.subviews.count, previousSuperview.subviews.count))
589
+ }
590
+
591
+ parent.view = container
592
+ container.addSubview(webView)
593
+ webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
594
+ webView.frame = container.bounds
595
+ moveNativeChrome(from: webView, to: container)
596
+
597
+ systemTabRootContainer = container
598
+ originalWebViewSuperview = container
599
+ originalWebViewIndex = 0
600
+ originalWebViewAutoresizingMask = webView.autoresizingMask
601
+ return container
602
+ }
603
+
604
+ private func moveNativeChrome(from webView: UIView, to container: UIView) {
605
+ if let navContainer = navContainer,
606
+ navContainer.superview === webView {
607
+ container.addSubview(navContainer)
608
+ }
609
+ }
610
+
566
611
  private func applySystemTabBarItems(_ items: [UITabBarItem], selectedIndex: Int?, animated: Bool) {
567
612
  guard let tabBarController = tabBarController else {
568
613
  return
@@ -679,7 +724,10 @@ public class NativeNavigationPlugin: CAPPlugin, CAPBridgedPlugin, UITabBarContro
679
724
 
680
725
  captureOriginalWebViewPlacementIfNeeded(webView)
681
726
  clearHostedWebViews(matching: webView, except: selectedController)
682
- selectedController.host(webView: webView)
727
+ guard selectedController.host(webView: webView) else {
728
+ isWebViewHostedInSystemTabController = false
729
+ return
730
+ }
683
731
  clearHostedWebViews(matching: webView, except: selectedController)
684
732
  isWebViewHostedInSystemTabController = true
685
733
  }
@@ -1367,7 +1415,7 @@ private final class NativeNavigationBar: UINavigationBar {
1367
1415
  }
1368
1416
  }
1369
1417
 
1370
- private final class NativeNavigationTabController: UITabBarController {
1418
+ final class NativeNavigationTabController: UITabBarController {
1371
1419
  override func viewDidLoad() {
1372
1420
  super.viewDidLoad()
1373
1421
  view.backgroundColor = .clear
@@ -1376,7 +1424,7 @@ private final class NativeNavigationTabController: UITabBarController {
1376
1424
  }
1377
1425
  }
1378
1426
 
1379
- private final class NativeNavigationTabContentController: UIViewController {
1427
+ final class NativeNavigationTabContentController: UIViewController {
1380
1428
  private weak var hostedWebView: UIView?
1381
1429
 
1382
1430
  override func loadView() {
@@ -1402,16 +1450,21 @@ private final class NativeNavigationTabContentController: UIViewController {
1402
1450
  hostedWebView = nil
1403
1451
  }
1404
1452
 
1405
- func host(webView: UIView) {
1406
- if hostedWebView !== webView {
1407
- hostedWebView = webView
1453
+ @discardableResult
1454
+ func host(webView: UIView) -> Bool {
1455
+ guard view !== webView, !view.isDescendant(of: webView) else {
1456
+ hostedWebView = nil
1457
+ return false
1408
1458
  }
1459
+
1460
+ hostedWebView = webView
1409
1461
  if webView.superview !== view {
1410
1462
  webView.removeFromSuperview()
1411
1463
  view.addSubview(webView)
1412
1464
  }
1413
1465
  webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
1414
1466
  webView.frame = view.bounds
1467
+ return true
1415
1468
  }
1416
1469
  }
1417
1470
 
@@ -1,19 +1,37 @@
1
1
  import XCTest
2
+ import UIKit
2
3
  @testable import NativeNavigationPlugin
3
4
 
4
5
  class NativeNavigationTests: XCTestCase {
5
- func testEcho() {
6
- let implementation = NativeNavigation()
7
- let value = "Hello, World!"
8
- let result = implementation.echo(value)
9
-
10
- XCTAssertEqual(value, result)
11
- }
12
-
13
6
  func testGetPluginVersion() {
14
7
  let implementation = NativeNavigation()
15
8
  let result = implementation.getPluginVersion()
16
9
 
17
10
  XCTAssertEqual("native", result)
18
11
  }
12
+
13
+ func testTabContentControllerHostsWebView() {
14
+ let webView = UIView()
15
+ let originalContainer = UIView()
16
+ let controller = NativeNavigationTabContentController()
17
+ _ = controller.view
18
+
19
+ originalContainer.addSubview(webView)
20
+
21
+ XCTAssertTrue(controller.host(webView: webView))
22
+ XCTAssertEqual(webView.superview, controller.view)
23
+ XCTAssertEqual(webView.frame, controller.view.bounds)
24
+ }
25
+
26
+ func testTabContentControllerRejectsLayerCycle() {
27
+ let webView = UIView()
28
+ let controller = NativeNavigationTabContentController()
29
+ _ = controller.view
30
+
31
+ webView.addSubview(controller.view)
32
+
33
+ XCTAssertFalse(controller.host(webView: webView))
34
+ XCTAssertNil(webView.superview)
35
+ XCTAssertEqual(controller.view.superview, webView)
36
+ }
19
37
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-native-navigation",
3
- "version": "8.0.14",
3
+ "version": "8.0.15-beta.pr12.18.1",
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",
@@ -14,7 +14,7 @@
14
14
  "ios/Sources",
15
15
  "ios/Tests",
16
16
  "Package.swift",
17
- "CapgoNativeNavigation.podspec"
17
+ "CapgoCapacitorNativeNavigation.podspec"
18
18
  ],
19
19
  "author": "Martin Donadieu <martin@capgo.app>",
20
20
  "license": "MPL-2.0",
@@ -35,7 +35,7 @@
35
35
  ],
36
36
  "scripts": {
37
37
  "verify": "bun run verify:ios && bun run verify:android && bun run verify:web",
38
- "verify:ios": "xcodebuild -scheme CapgoNativeNavigation -destination generic/platform=iOS",
38
+ "verify:ios": "xcodebuild -scheme CapgoCapacitorNativeNavigation -destination generic/platform=iOS",
39
39
  "verify:android": "cd android && ./gradlew clean build test && cd ..",
40
40
  "verify:web": "bun run build",
41
41
  "lint": "bun run eslint && bun run prettier -- --check && bun run swiftlint -- lint",