ストーリーボードの画像は、ここで少し誤解を招きます。
B にセグエすると、実際には B/C コンボにセグエされます。これは、NavControllers が常にスタックに少なくとも 1 つの viewController を持っているためです (これは、topViewController
と その[viewControllers objectAtIndex:0]
です)。
したがって、A から C への直接の関係があります。
そのコントローラーにアクセスする方法は、セグエがモーダルかプッシュかによって異なります。あなたの場合はモーダルですが、違いがわかるように両方について説明します。
どちらの場合でも、データを C に渡すには、ヘッダー ファイルでプロパティを宣言する必要があります。
@interface CviewController: UIViewContrller
@property (assign) int dataFromA;
@end
セグエを押す
プッシュ セグエでは、B ではなく、実際には C が destinationViewController です。実際、プッシュ セグエは、A と C の両方の UINavigationController である B によって管理されます。プッシュ セグエの背後にあるコードは、次の形式です。
[self.navigationController pushViewController:otherViewController];
AviewController の prepareForSegue では:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
CviewController* controller = segue.destinationViewController;
[controller setDataFromA:self.data];
}
ストーリーボードでは、共通の UINavigationController を共有しない2 つの viewController の間にプッシュ セグエ ラインを作成することができます。ただし、これを実行すると、クラッシュ エラーが発生します。
「セグエ 'pushC' のナビゲーション コントローラーが見つかりませんでした。プッシュ セグエは、ソース コントローラーが UINavigationController のインスタンスによって管理されている場合にのみ使用できます。
すべての優れたプッシュ セグエの背後には、Navigation Controller があります。
モーダルセグエ
モーダル Segue の背後に隠れているコードは UIViewController メソッドです
- (void)presentViewController:(UIViewController *)viewControllerToPresent
NavController/ViewController コンボへのモーダル セグエでは、デスティネーション viewController は、セグエ ラインが指すものです。それがviewControllerを指している場合、それはsegue.destinationControllerです(そしてUINavigationControllerは無視されますが、これはここで必要なものではありません)。この場合のように UINavigationController を指している場合、それが destinationController になります。しかし、ナビゲーション コントローラーの topViewController になるため、viewController にアクセスするのは簡単です。
AviewController の prepareForSegue では:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
CviewController* controller =
(CviewController*)[[segue destinationViewController] topViewController];
[controller setDataFromA:self.data];
}
この場合、古いスタイルの [[メッセージ パッシング] 構文] を使用する必要があることに注意してください。modern.property.syntax を使用すると、コンパイル エラーが発生します。これは、プログラムが desinationViewController のタイプを認識しておらず、topViewController を未知のタイプのプロパティとして受け入れることを拒否しているためです。しかし、未知のタイプに [[本当のメッセージ] を送信] することは喜ばしいことです。また、コンパイラの警告を避けるために (typecast*) する必要があります。