如何检查对象是否是仅使用Swift标准库在运行时计算的类(包括子类)的实例?

时间:2018-12-22 02:30:17

标签: swift

is采用的类型必须在编译时进行硬编码。 isKindOfClass:接受一个表达式,其值可以在运行时计算。

我想检查对象是否是仅使用Swift标准库在运行时计算的类(包括子类)的实例?

编辑: 注意:我的问题可能与下面的问题无关。

我只是在调查与我的一个示例测试应用程序构建有关的问题,以使用协调器模式。

我在UITabBarController中有4个选项卡,单击底部的选项卡栏项时,我需要用户导航到主视图(第一个视图)。

例如: HomeviewController(“主主页”选项卡)-> FirstHomeVC-> SecondHomeVC

当用户从HomeviewController导航到SecondHomeVC并再次单击底部的“主页”选项卡时,我需要用户导航回到HomeviewController,而不要停留在同一SecondHomeVC上。

这是我的课程:只是想了解课程。

final class RootNavigationCoordinator: Coordinator, NavigationCoordinator {

    enum Tab {
        //case home, map, settings
        case home, map, profile, settings
    }

    enum Transition: TransitionType {
        case toTab(Tab)   
    }

    override var rootViewController: UIViewController {
        return rootController
    }

    private let parentController: UIViewController
    private let rootController: UITabBarController
    private let rootControllerViewModel: RootControllerViewModel

    weak var delegate: RootDelegate?

    private var selectedCoordinator: TabCoordinatorType?

    required init(rootViewController: UIViewController, tabCoordinators: [TabCoordinatorType]) {
        self.parentController = rootViewController
        self.rootController = UITabBarController()
        self.rootControllerViewModel = RootControllerViewModel()
        super.init()

        childCoordinators = tabCoordinators
        rootController.delegate = rootControllerViewModel
        rootControllerViewModel.navigationCoordinator = self
        selectedCoordinator = tabCoordinators.first
    }

    override func start(animated: Bool) {
        setupRootController(animated: animated)
        delegate?.rootPresenterDidFinishLaunching()
    }

    private func setupRootController(animated: Bool) {
        let coordinatorControllers = childCoordinators.map { $0.rootViewController }
        rootController.viewControllers = coordinatorControllers

        rootController.tabBar.barTintColor = UIColor.white

        // Brings the title a bit closer to the icon
        let verticalAdjustment: CGFloat = -2
        UITabBarItem.appearance().titlePositionAdjustment = UIOffset(horizontal: 0, vertical: verticalAdjustment)
        if let navController = parentController as? UINavigationController {
            navController.pushViewController(rootController, animated: animated)
        } else {
            parentController.present(rootController, animated: animated, completion: nil)
        }
    }

    func performTransition(_ transition: TransitionType) {
        guard let transition = transition as? RootNavigationCoordinator.Transition else { return }

        switch transition {
            case .toTab(let tab):
                print("PerformTransition TaB : \(tab)")
                select(tab: tab)
                // If you need to transition to a nested view
        }
    }

    private func select(tab: Tab) {
        selectedCoordinator = getCoordinator(for: tab)
        print("Select Coordinator: \(String(describing: selectedCoordinator))")
        rootController.switchToTab(tab)
    }

    private func getCoordinator(for tab: Tab) -> TabCoordinatorType? {
        return childCoordinators.filter {
            switch tab {
                case .home:
                    return $0 is HomeNavigationCoordinator
                case .map:
                    return $0 is MapNavigationCoordinator
                case .profile:
                    return $0 is ProfileNavigationCoordinator
                case .settings:
                    return $0 is SettingsNavigationCoordinator
            }
        }.first as? TabCoordinatorType
    }
}

extension UITabBarController {

    func tab(for viewController: UIViewController) -> RootNavigationCoordinator.Tab? {
        if let navController = viewController as? UINavigationController {
            //print("tab: \(navController.viewControllers.first!)")
            return tab(for: navController.viewControllers.first!)
        }
        switch viewController {
            case is HomeViewController:
                return .home

            case is MapMainViewController:
                return .map

            case is ProfileMainViewController:
                return .profile

            case is SettingsMainViewController:
                return .settings

            default:
                return nil
        }
    }

    func switchToTab(_ tab: RootNavigationCoordinator.Tab) {
        guard let viewController = viewControllers?.filter({ (viewController) -> Bool in
            print("Switch to tab: \(tab) with viewController: \(viewController)")
            switch tab {
                case .home:
                    return contains(viewController: viewController, of: HomeViewController.self)

                case .map:
                    return contains(viewController: viewController, of: MapMainViewController.self)

                case .profile:
                    return contains(viewController: viewController, of: ProfileMainViewController.self)

                case .settings:
                    return contains(viewController: viewController, of: SettingsMainViewController.self)

            }
        }).first else { return }


        selectedViewController = viewController
    }

    private func contains<T>(viewController: UIViewController, of type: T.Type) -> Bool {
        if let navController = viewController as? UINavigationController {
            return navController.viewControllers.filter { $0 is T }.count > 0
        }
        return viewController is T
    }
}

0 个答案:

没有答案