pkino
@pkino (Ikuhide Kinoshita)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

型自体を取得する変数の定義の仕方

解決したいこと

型自体を扱いたい時に、それを変数に入れる方法はありますでしょうか?

発生している問題

以下のようなextensionを定義しているとします。

extension UINavigationController {
    func findViewController<T: UIViewController>(_: T.Type) -> T? {
        viewControllers
            .compactMap { $0 as? T }
            .first
    }
}

NavigationConrollerの中のあるViewControllerから、このメソッドを利用して、そのスタック内にあるFirstViewControllerというクラスのViewControllerに遷移したいとします。

正しく動く例:

     guard let navigationController = navigationController,
           let targetViewController = navigationController.findViewController(FirstViewController.self)
     else { return }
     navigationController.popToViewController(targetViewController, animated: true)

一方で、条件によってFirtstViewControllerかSecondViewControllerのどちらかに分岐させたいとします。そして、それを実現するため、findViewControllerの引数に入れるための変数を準備し、以下のように実装します。
すると、findViewControllerの中のT.self(=引数で渡しているtargetType)が、FirtstViewControllerやSecondViewControllerのクラスではなく、UIViewControllerと認識されてしまいます。

     let targetType= isSelected ? FittingViewController.self : GoodsListNormalViewController.self

     guard let navigationController = navigationController,
           let targetViewController = navigationController.findViewController(targetTypw.self)
     else { return }
     navigationController.popToViewController(targetViewController, animated: true)

その結果意図しないViewController、ここでは1番最初のViewControllerに遷移してしまうという現象が発生してます。
上記のように、型自身を利用したい場合に、変数に入れる方法はありませんでしょうか?

0

1Answer

    func findVC<T: UIViewController>(inputType: T.Type) -> T? {
        viewControllers
            .filter { type(of: $0) == inputType }
            .compactMap { $0 as? T }
            .first
    }

なぜ動かないのかという問いには答えていないのですが、おそらくこのようにしたら動くと思います。

1Like

Comments

  1. @pkino

    Questioner

    ありがとうございます!
    無事に動きました!

Your answer might help someone💌