55385


[![画像の説明をここに入力](https://i.stack.imgur.com/KRfNI.png)](https://i.stack.imgur.com/KRfNI.png)

上記画像のように、単なる`UIViewController`から`UIViewController`に`Show Detail(e.g.
Replace)`をつなげると、`Present Modally` と非常に似たアニメーションをして画面が切り替わります。

`Show Detail(e.g.
Replace)`について検索すると`UISplitViewController`についてのみ言及されているページばかりひっかります。`UISplitViewController`を使っていない上記画像のような文脈ではどのような挙動が期待されているのでしょうか？


CC BY-SA 4.0
2019-05-31T02:15:08.900
55382
2019-05-31T04:00:16.767
9008
question
swift ios xcode
Show Detail(e.g. Replace)を UISplitViewController 以外の文脈で使うとどうなりますか？


まず大前提として、このタイプのセグエは、

  * `UISplitViewController`を陽に使っている
  * (Master-Detailプロジェクトのように)デバイスによって`UISplitViewController`が使われたり、使われなかったりする

と言うことを想定しているので、掲載のように、全く`UISplitViewController`が使用されていない場面では使う意味がありません。

* * *

しかし、上記の2つ目の場合にうまく動くようにその動作が定義されているので、`UISplitViewController`が存在しない場合にもそれっぽい動作をするようになっています。

[View Controller Programming Guide for
iOS](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/)

(すでにArchive入りしちゃってますが、現在でも大変有用です。んが、代替となる新しいドキュメントは見当たらない上、日本語版はArchiveもされずにリンク切れになっています…。)

その [Using
Segue](https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html)
の項:

> **Show Detail (Replace)**
>
> This segue displays the new content using the
> [showDetailViewController:sender:](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621432-showdetailviewcontroller)
> method of the target view controller. This segue is relevant only for view
> controllers embedded inside a
> [UISplitViewController](https://developer.apple.com/documentation/uikit/uisplitviewcontroller)
> object. With this segue, a split view controller replaces its second child
> view controller (the detail controller) with the new content.  
>  Most other view controllers present the new content modally. UIKit uses the
> [targetViewControllerForAction:sender:](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621415-targetviewcontroller)
> method to locate the source view controller.

ざっくり訳:

> **このセグエは新コンテンツを`showDetailViewController(_:sender:)`メソッドを使って表示します。**
> このセグエは`UISplitViewController`の中に埋め込まれたview
> controllerに対してだけ意味があります。このセグエを使うとsplit view controllerは2つ目の子view
> controller(詳細側)を新コンテンツで置き換えます。  
>  **他の殆どのview controllerでは、新コンテンツをモーダルに表示します。** UIKitはソースとなるview
> controllerを決定するために、`targetViewController(forAction:sender:)`メソッドを使います。

肝心なのは太線部ですが、各メソッドの詳細もよく読んでまとめると

  * このセグエは`showDetailViewController(_:sender:)`メソッドを使って表示する

  * `UIViewController`は`showDetailViewController(_:sender:)`メソッドのデフォルト実装を持っている

当然通常のview controllerは大抵それを継承していて、そのデフォルト実装は、

`targetViewController(forAction:sender:)`を使ってview
controller階層を這い上がりながら、`showDetailViewController(_:sender:)`メソッドを **オーバライド**
(単に「実装」ではない)しているview controllerを探す

    * 見つかればそのview controllerの`showDetailViewController(_:sender:)`メソッドを呼び出す
    * 見つからなければwindowのroot view controllerからコンテンツをモーダルに表示する
  * `UISplitViewController`は`showDetailViewController(_:sender:)`メソッドを **オーバライド** している

その動作は「詳細側」のコンテンツの入れ替え

と言う感じになります。

* * *

従って、`UISplitViewController`が絡んでいないあなたの例のような場合、「root view
controllerである黄色VCからオレンジVCがモーダルに表示される」と言うのが、(ドキュメントから)期待される動作、と言うことになります。

また黄色VC用のクラスで`showDetailViewController(_:sender:)`メソッドをオーバライドして挙動を書き換える(`super.showDetailViewController(_:sender:)`は呼んではいけない)と動作が変わるはずです。

ただ、このセグエは最初の想定例2つ目のように、「実行環境によって`UISplitViewController`が使われている時といない時がある」場合に、実行時の詳細を隠蔽するために使うものなので、自分で特殊なcontainer
view
controllerを実装するんでない限り、`showDetailViewController(_:sender:)`メソッドをオーバライドなんて事はやりません。


CC BY-SA 4.0
2019-05-31T03:52:37.643
55385
2019-05-31T04:00:16.767
2019-05-31T04:00:16.767
13972
13972
55382
answer