I have a custom UINavigationController
which performs some pushing and popping actions.
I using SwiftUI within a UIKit application so a few of the view controllers within the UINavigationController are UIHostingControllers
In various parts of my code I have UIHostingController(rootView: ArticleView())
or UIHostingController(rootView: RatingView())
and some others
I wanted to specifically identify if the Navigation controller was going to push the article view or the rating view so what I did was:
protocol TabBarCompatible: View { }
extension ArticleView: TabBarCompatible { }
extension RatingView: TabBarCompatible { }
Then when I am going through the view controllers in my Navigation controller, I check to see if the destination is like one of the above:
if let destinationView = self as? UIHostingController<AnyView>,
destinationView.rootView is any TabBarCompatible
Now the cast to UIHostingController<AnyView>
itself fails which probably could succeed if when I created the SwiftUI views, I would need to do UIHostingController(rootView: AnyView(ArticleView()))
– however:
- What I really wish to check is `if let destinationView = self as? UIHostingController
- I prefer not to wrap to AnyView unless its the last resort as I will have to do this in many places
Another option could also be to hold all the possibilities I wish to check in an array and keep
let swiftUIControllers = [UIHostingController<ArticleView>, UIHostingController<RatingView>]
// loop through the swiftUIControllers and compare the current controller using isKind(of: )
Is there any other / better way to cast a UIViewController to a UIHostingController generically without knowing the rootView of the UIHostingController ?
2
Answers
If you just want to check if the
rootView
conforms toTabBarCompatible
and don’t care about anything else aboutrootView
, you can introduce a new protocol like this:Then you can check
if destination is (any TabBarCompatibleViewController)
.If you remove the
: View
constraint onTabBarCompatible
, you can reuseTabBarCompatible
instead of writing a new protocol,You can refer to the following implementation.
You can use it like this