yashigani?.days

週刊少年ジャンプについてだらだら書きます

switchとType Castingで安全なprepareForSegueを実装する

画面遷移時に実行されるprepareForSegue:sender:ですが,Objective-Cで実装するといいかんじに不安な実装が完成します.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqual:@"HogeSegue"]) {
        HogeViewController *vc = (HogeViewController *)segue.destinationViewController;
        // 依存を注入
    }
    else if ([segue.identifier isEqual:@"FugaSegue"]) {
        UINavigationController *nc = (UINavigationController *)segue.destinationViewController;
        FugaViewController *vc = (FugaViewController *)nc.childViewControllers.firstObject
        // 依存を注入
    }
}

愚直にコンバートもできますが,SwiftではswitchとType Castingを組み合わせて実装してみます.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    switch segue.destinationViewController {
    case let vc as HogeViewController:
        // 依存の注入
    case let nc as UINavigationController:
        switch nc.childViewControllers.first {
        case let vc as FugaViewController:
            // 依存の注入
        default: ()
        }
    default: ()
    }
}

Objective-Cで実装するときは,いつもUINavigationControllerから子のView Controllerを取り出す実装がモヤモヤしていたのですが,switchとType Castingを組み合わせると少しいいかんじにまとまります. UIStoryboardSegueを使った画面遷移の実装はどうしても不安になりがちですが,これくらい落ち着いた実装だと少し安心できます.

もちろん分岐が無いときは,if letするのもアリです.

if let vc = (segue.destinationViewController as? UINavigationController).childViewControllers.first as FugaViewController) {
    // 長い...
}

参考