如何在 Swift 中向下转换 UIViewController

How to downcast UIViewController in Swift

我有几个继承自 UIViewController 的视图控制器。视图嵌入在选项卡栏控制器中。我实现了一个自定义视图转换控制器,以便在我点击标签栏项目时可以切换视图。我是否有可能知道 toVC 和 fromVC 的确切含义以便我可以执行不同的视图转换?好像那样!不成功。当我使用 as? 时,变量没有设置为 true。什么是正确的投射方式或任何其他方式来检查它是什么视图?谢谢

    func tabBarController(tabBarController: UITabBarController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    var detail = false
    var item = false
    if var controller = toVC as? DetailViewController {
        detail = true
    }
    if var controller = toVC as? ItemViewController {
        item = true
    }
    ...
    return threeDAnimationController
}

在 Swift 中,您可以使用 is 运算符来检查 class 是什么,在 objc 中,您可以使用 isKindOfClass 方法:

在 objc 中你可以这样做:

if ([toVC isKindOfClass:[DetailViewController class]]) { detail = true }

在 swift 你可以做:

if toVC is DetailViewController { detail = true }

您可能 运行 遇到的一个潜在问题是将视图控制器推入 UINavigationController,因此您必须弄清楚什么是可见视图控制器。我有这个方便的扩展:

extension UIViewController {
    var contentViewController: UIViewController? {
        if let navigationController = self as? UINavigationController {
            return navigationController.visibleViewController
        } else {
            return self
        }
    }
}

您可以像这样将其合并到您的代码中:

func tabBarController(tabBarController: UITabBarController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    var detail = false
    var item = false
    if var controller = toVC.contentViewController as? DetailViewController {
        detail = true
    }
    if var controller = toVC.contentViewController as? ItemViewController {
        item = true
    }
    ...
    return threeDAnimationController
}

您可以只创建一个开关,然后在其中执行您想要的转换:

switch toVC {
    case is ItemViewController:
        // do some stuff, should already casted I think
    case is DetailViewController:
        // again do some stuff
    default: break
}

正如其他一些用户在这里提到的那样,如果您将 viewcontroller 包装在 Navigation 或 UISplitViewController 中,您可能 运行 会遇到麻烦,因此只需创建一个扩展,例如 Julian J. Tejera 在他的文章中已经提到回答。 (如果您随时支持 iPad,还可以添加 UISplitViewController 作为案例)