0

My UITabBarController has a method to switch to a tab of a certain View Controller type. The method takes a parameter for this VC type called newVC. Its type is UIViewController.Type. The method finds a tab with that type, and switches to it.

The method works fine when the newVC type is hard-coded inside the method. But when I put it as a variable, XCode complains that the newVC param isn't available inside the method.

For the love of god, why?

func animateToVC(_ newVC: UIViewController.Type){
      guard let VCs = viewControllers else { return }

      for (listIndex, vc) in VCs.enumerated(){
         guard let navController = vc as? CustomNavBarController,
               navController.rootViewController is newVC else { continue } --> "Cannot find type 'newVC' in scope"

         animateToView(atTabIndex: listIndex)
         selectedIndex = listIndex
      }
   }
theogood
  • 85
  • 1
  • 1
  • 7

1 Answers1

1

You cannot use a variable with the is keyword in Swift for type checking. However, you can make the method generic and use the generic type parameter instead.

func animateToVC<ViewControllerType: UIViewController>(_ newVC: ViewControllerType.Type) {
    guard let VCs = viewControllers else { return }

    for (listIndex, vc) in VCs.enumerated(){
        guard let navController = vc as? CustomNavBarController,
              navController.rootViewController is ViewControllerType else { continue }

        animateToView(atTabIndex: listIndex)
        selectedIndex = listIndex
    }
}
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • That did it! Thank you Bonus points question: the call site is now: animateToVC(ExampleVC.self) but XCode complains if I don't use the .self extension. Why? – theogood Mar 17 '22 at 15:46
  • 1
    @theogood calling `.self` on a type returns the meta type (type of the type) and that's what the method expects - due to `.Type`. For more info, check [this](https://stackoverflow.com/a/41709040/4667835) excellent answer that explains Swift meta types. – Dávid Pásztor Mar 17 '22 at 15:48