在switch语句中检查多个条件

时间:2018-08-03 10:27:03

标签: swift enums switch-statement

我有一个Swift函数,该函数使用switch语句对各种枚举进行操作,但是我还需要同时检查其他条件。我能想到的最好的解决方案是使用嵌套开关(有效),但我想知道是否有更优雅的方法(快捷?)?

代码很不言自明:

func transitionTo(scene: Scene, transition: SceneTransitionType) -> Observable<Void> {

let subject = PublishSubject<Void>()
let viewController = scene.viewController()

switch viewController {
case is UISplitViewController:
    switch transition {
    case .root:
        window.rootViewController = viewController
        subject.onCompleted()
    default:
        fatalError("UISplitViewController can only be exist at the root of the view hierachy")
    }
default:
    switch transition {
    case .root:
        window.rootViewController = viewController
        subject.onCompleted()
    case .push(let animated):
        guard let nc = currentViewController as? UINavigationController else {
            fatalError("Unab;e to push a view controlled without an existing navigation controller")
        }
        _ = nc.rx.delegate // one-off sub to be notified when push complete
            .sentMessage(#selector(UINavigationControllerDelegate.navigationController(_:didShow:animated:)))
            .map { _ in }
            .bind(to: subject)
        nc.pushViewController(viewController, animated: animated)
        currentViewController = SceneCoordinator.topViewControllerInStackWith(root: viewController).first!
    case .modal(let animated):
        currentViewController.present(viewController, animated: animated) {
            subject.onCompleted()
        }
        currentViewController = SceneCoordinator.topViewControllerInStackWith(root: viewController).first!
}

1 个答案:

答案 0 :(得分:1)

据我所知,这是使用单个switch语句的最佳方法。

func transitionTo(scene: Scene, transition: SceneTransitionType) -> Observable<Void> {

    let subject = PublishSubject<Void>()
    let viewController = scene.viewController()

    switch transition {
    case .root:
        window.rootViewController = viewController
        subject.onCompleted()
    case .push(let animated):
        if viewController is UISplitViewController {
            fatalError("UISplitViewController can only be exist at the root of the view hierachy")
            return
        }
        guard let nc = currentViewController as? UINavigationController else {
            fatalError("Unab;e to push a view controlled without an existing navigation controller")
        }
        _ = nc.rx.delegate // one-off sub to be notified when push complete
            .sentMessage(#selector(UINavigationControllerDelegate.navigationController(_:didShow:animated:)))
            .map { _ in }
            .bind(to: subject)
        nc.pushViewController(viewController, animated: animated)
        currentViewController = SceneCoordinator.topViewControllerInStackWith(root: viewController).first!
    case .modal(let animated):
        if viewController is UISplitViewController {
            fatalError("UISplitViewController can only be exist at the root of the view hierachy")
            return
        }
        currentViewController.present(viewController, animated: animated) {
            subject.onCompleted()
        }
        currentViewController = SceneCoordinator.topViewControllerInStackWith(root: viewController).first!
    }
}