@@ -19,67 +19,69 @@ public final class Routing<T: RouterIdentifiable> {
1919 public var onPresent : ( ( T , Bool ) -> Void ) ?
2020 public var onPopLast : ( ( Int , Bool ) -> Void ) ?
2121 public var onPopToRoot : ( ( Int ? , Bool ) -> Void ) ?
22-
22+
2323 public var currentRoutes : [ T ] {
2424 return routes
2525 }
26-
26+
2727 public init ( initial: T ? = nil ) {
2828 if let initial = initial { push ( initial) }
2929 }
30-
30+
3131 public func makeRoot( _ route: T , animated: Bool = true , needValidate: Bool = false ) {
3232 guard !( needValidate && routes. last? . key == route. key) else { return }
3333 routes = [ route]
3434 onMakeRoot ? ( route, animated)
3535 }
36-
36+
3737 public func push( _ route: T , animated: Bool = true , needValidate: Bool = false ) {
3838 guard !( needValidate && routes. last? . key == route. key) else { return }
3939 routes. append ( route)
40+ print ( " Routing pushed: \( route) " )
4041 onPush ? ( route, animated)
4142 }
42-
43+
4344 public func present( _ route: T , animated: Bool = true , needValidate: Bool = false ) {
4445 guard !( needValidate && routes. last? . key == route. key) else { return }
4546 routes. append ( route)
47+ print ( " Routing presented: \( route) " )
4648 onPresent ? ( route, animated)
4749 }
48-
50+
4951 public func pop( animated: Bool = true ) {
5052 guard !routes. isEmpty else { return }
5153 let popped = routes. removeLast ( )
5254 print ( " Routing popped: \( popped) " )
5355 onPopLast ? ( 1 , animated)
5456 }
55-
57+
5658 public func popTo( last index: Int , animated: Bool = true ) {
5759 guard !routes. isEmpty else { return }
5860 let elementsToRemove = min ( index - 1 , routes. count - 1 )
5961 routes. removeLast ( elementsToRemove)
6062 onPopLast ? ( index, animated)
6163 }
62-
64+
6365 public func popTo( _ route: T , inclusive: Bool = false , animated: Bool = true ) {
6466 guard let foundIndex = routes. lastIndex ( where: { $0 == route } ) else { return }
6567 let indexToPopTo = inclusive ? foundIndex : foundIndex + 1
6668 guard indexToPopTo != 0 else {
6769 popToRoot ( index: nil , animated: animated)
6870 return
6971 }
70-
72+
7173 let numToPop = routes. count - indexToPopTo
7274 routes. removeLast ( numToPop)
7375 onPopLast ? ( numToPop, animated)
7476 }
75-
77+
7678 public func popToRoot( index: Int ? = nil , animated: Bool = true ) {
7779 onPopToRoot ? ( index, animated)
7880 if routes. count > 1 {
7981 routes. removeSubrange ( 1 ..< routes. count)
8082 }
8183 }
82-
84+
8385 public func onSystemPop( ) {
8486 guard !routes. isEmpty else { return }
8587 let popped = routes. removeLast ( )
@@ -90,12 +92,12 @@ public final class Routing<T: RouterIdentifiable> {
9092public struct RouteProvider < T: RouterIdentifiable , Screen: View > : View {
9193 private let router : Routing < T >
9294 @ViewBuilder private let routeMap : ( T ) -> Screen
93-
95+
9496 public init ( _ router: Routing < T > , @ViewBuilder _ routeMap: @escaping ( T ) -> Screen ) {
9597 self . router = router
9698 self . routeMap = routeMap
9799 }
98-
100+
99101 public var body : some View {
100102 NavigationControllerHost ( router: router, routeMap: routeMap)
101103 . edgesIgnoringSafeArea ( . all)
@@ -105,35 +107,35 @@ public struct RouteProvider<T: RouterIdentifiable, Screen: View>: View {
105107struct NavigationControllerHost < T: RouterIdentifiable , Screen: View > : UIViewControllerRepresentable {
106108 let router : Routing < T >
107109 @ViewBuilder var routeMap : ( T ) -> Screen
108-
110+
109111 func makeUIViewController( context: Context ) -> PopAwareUINavigationController {
110112 let navigation = PopAwareUINavigationController ( )
111113 navigation. navigationBar. isHidden = true
112114 setupRouterCallbacks ( in: navigation)
113115 setupInitialRoutes ( in: navigation)
114116 return navigation
115117 }
116-
118+
117119 private func setupRouterCallbacks( in navigation: PopAwareUINavigationController ) {
118120 navigation. popHandler = { router. onSystemPop ( ) }
119121 navigation. stackSizeProvider = { router. currentRoutes. count }
120-
122+
121123 router. onMakeRoot = { route, animated in
122124 let viewController = UIHostingController ( rootView: routeMap ( route) )
123125 navigation. setViewControllers ( [ viewController] , animated: animated)
124126 }
125-
127+
126128 router. onPush = { route, animated in
127129 let viewController = UIHostingController ( rootView: routeMap ( route) )
128130 navigation. pushViewController ( viewController, animated: animated)
129131 }
130-
132+
131133 router. onPresent = { route, animated in
132134 let viewController = UIHostingController ( rootView: routeMap ( route) )
133135 viewController. modalPresentationStyle = . overFullScreen
134- navigation . present ( viewController, animated: animated)
136+ rootViewController ? . present ( viewController, animated: animated)
135137 }
136-
138+
137139 router. onPopLast = { numToPop, animated in
138140 let popTo = navigation. viewControllers. count - numToPop - 1
139141 if numToPop == navigation. viewControllers. count {
@@ -142,7 +144,7 @@ struct NavigationControllerHost<T: RouterIdentifiable, Screen: View>: UIViewCont
142144 navigation. popToViewController ( navigation. viewControllers [ popTo] , animated: animated)
143145 }
144146 }
145-
147+
146148 router. onPopToRoot = { tabIndex, animated in
147149 navigation. popToRootViewController ( animated: animated)
148150 if let tabIndex = tabIndex {
@@ -154,34 +156,53 @@ struct NavigationControllerHost<T: RouterIdentifiable, Screen: View>: UIViewCont
154156 }
155157 }
156158 }
157-
159+
160+ private var rootViewController : UIViewController ? {
161+ UIApplication . shared. connectedScenes
162+ . compactMap { $0 as? UIWindowScene }
163+ . compactMap { $0. windows. first { $0. isKeyWindow } }
164+ . first? . rootViewController. flatMap ( getTopViewController)
165+ }
166+
167+ private func getTopViewController( from viewController: UIViewController ) -> UIViewController {
168+ if let presented = viewController. presentedViewController {
169+ return getTopViewController ( from: presented)
170+ } else if let navigation = viewController as? UINavigationController {
171+ return getTopViewController ( from: navigation. visibleViewController ?? viewController)
172+ } else if let tabBar = viewController as? UITabBarController {
173+ return getTopViewController ( from: tabBar. selectedViewController ?? viewController)
174+ } else {
175+ return viewController
176+ }
177+ }
178+
158179 private func setupInitialRoutes( in navigation: PopAwareUINavigationController ) {
159180 for path in router. currentRoutes {
160181 navigation. pushViewController ( UIHostingController ( rootView: routeMap ( path) ) , animated: true )
161182 }
162183 }
163-
184+
164185 func updateUIViewController( _ navigation: PopAwareUINavigationController , context: Context ) {
165186 navigation. navigationBar. isHidden = true
166187 }
167-
188+
168189 static func dismantleUIViewController( _ navigation: PopAwareUINavigationController , coordinator: ( ) ) {
169190 navigation. viewControllers = [ ]
170191 navigation. popHandler = nil
171192 }
172-
193+
173194 typealias UIViewControllerType = PopAwareUINavigationController
174195}
175196
176197class PopAwareUINavigationController : UINavigationController , UINavigationControllerDelegate {
177198 var popHandler : ( ( ) -> Void ) ?
178199 var stackSizeProvider : ( ( ) -> Int ) ?
179-
200+
180201 override func viewDidLoad( ) {
181202 super. viewDidLoad ( )
182203 delegate = self
183204 }
184-
205+
185206 func navigationController( _ navigationController: UINavigationController , didShow _: UIViewController , animated _: Bool ) {
186207 if let stackSizeProvider = stackSizeProvider, stackSizeProvider ( ) > navigationController. viewControllers. count {
187208 popHandler ? ( )
0 commit comments