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
}
}