3

迅速に、switch ステートメントの優れた機能を使用して、宛先ビュー コントローラーのタイプprepare(segue:)に基づいてケースを作成できます。

例:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    switch segue.destination {

    case let detailViewController as DetailViewController:
      detailViewController.title = "DetailViewController"
    }
    case let otherViewController as OtherViewController:
      otherViewController.title = "OtherViewController"
    }
}

しかし、セグエが分割ビュー コントローラーによってトリガーされ、宛先がナビゲーション コントローラーであり、本当にやりたいことは、ナビゲーション コントローラーのトップ ビュー コントローラーのクラスをオンにすることである場合はどうなるでしょうか。

私はこのようなことをしたい:

case let nav as UINavigationController,
     let detailViewController = nav.topViewController as? DetailViewController:
    //case code goes here

複数の部分のif letオプションのバインディングで使用するのと同じ構造があります。

それはうまくいきません。代わりに、次のようなかなり面倒な構成を行う必要があります。

case let nav as UINavigationController
  where nav.topViewController is DetailViewController:
  guard let detailViewController = nav.topViewController as? DetailViewController
    else {
      break
  }
  detailViewController.title = "DetailViewController"

それは機能しますが、不必要に冗長に見え、意図がわかりにくくなります。Swift 3 でこのような switch ステートメントの場合、マルチパートのオプション バインディングを使用する方法はありますか?

4

5 に答える 5

1

switchandでこれを行う方法はないと思いますcaseが、探しているものに近いことをifand case(更新: Hamish が指摘したように、caseこのシナリオでは不要です) または単に通常の方法で行うことができます。 if let:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let nav = segue.destination as? UINavigationController, 
        let detailViewController = nav.topViewController as? DetailViewController {
        detailViewController.title = "DetailViewController"
    }

    if let otherViewController? = segue.destination as? OtherViewController {
        otherViewController.title = "OtherViewController"
    }
}

この例の switch ステートメントは、すべてのケースを処理するものとしてコンパイラによって実際に検証されることはないため (デフォルト ケースを作成する必要があるため)、switch単に代わりに使用する追加の利点はありません。if let

于 2016-11-17T17:07:47.653 に答える
0

私の意見では、このスイッチでフローを制御するには、セグエ識別子を使用する必要があります。しかし、あなたの質問に答えるには、これでうまくいくはずです。

switch (segue.destination as? UINavigationController)?.topViewController ?? segue.destination {
    ...
}

問題は、文法によると、ケース項目リストの項目ごとに 1 つのパターン (この場合はバインディング) しかないということです。入力に項目が 1 つしかないのに 2 つのパターンを使用したいので、入力を正規化するか (この場合は上記のように適切です)、項目リストを拡張します (この場合は不適切ですが、以下の例)。

switch ((segue.destination as? UINavigationController)?.topViewController, segue.destination) {
case (let tvc, let vc) where (tvc ?? vc) is DetailViewController:
    // TODO: If you await your DetailViewController in navigation or without.
    break
case (let tvc as DetailViewController, _):
    // TODO: If you await your DetailViewController in navigation but other vc is not in a navigation vc.
default:
    fatalError()
}
于 2017-03-14T12:39:33.837 に答える