同様の問題があり、「モーダルセグエチェーン」は制限されていませんでした。別の目的のために設計されたモーダルセグエについての回答と以下のコメントの議論に同意しますが、モーダルセグエの「水平反転」アニメーションが好きで、それらを複製する簡単な方法を見つけることができませんでした...また、一般的に私はモーダル コントローラーの連鎖など、ある目的のために設計されたものを別の目的のために使用することに問題があるとは思わないでください。繰り返される「部分的なカール」アニメーションも、一部のアプリの一部のシナリオに適用できます。
そこで、モーダル コントローラーのスタックをコントローラーのプロパティとして実装しました。
@interface ModalViewController : UIViewController
@property (nonatomic, retain) NSMutableArray *modalControllers;
@end
最初のモーダル セグエが実行されると、モーダルではないコントローラーの prepareForSegue メソッドでスタックが作成されます。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"modalSegue"]) {
ModalViewController *controller =
(ModalViewController *)[segue destinationViewController];
controller.modalControllers = [NSMutableArray arrayWithObject: controller];
}
}
あるモーダル コントローラーが別のコントローラーに移動すると、移動先がスタックに追加されます (ModalViewCotroller のメソッド内)。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"modalSegue"]) {
ModalViewController *destController =
(ModalViewController *)[segue destinationViewController];
// add destination controller to stack
destController.modalControllers = _modalControllers;
[destController.modalControllers addObject: destController];
}
}
スタック全体を一度に却下するのが最も難しい部分でした - 次の却下が完了する前に前のコントローラーを却下することはできないため、サイクルは機能しませんでした.まだ確認していませんが、これに依存していました):
- (IBAction)dismissAllModalControllers: (id)sender
{
// recursive block that dismisses one auth controller
// all these dances are to avoid leaks with ARC
typedef void (^voidBlockType)();
__block void (^dismissController) ();
voidBlockType __weak dismissCopy = ^void(void) {
dismissController();
};
dismissController = ^void(void) {
int count = [_modalControllers count];
if (count > 0) {
// get last controller
UIViewController *controller =
(UIViewController *)[_modalControllers lastObject];
// remove last controller
[_modalControllers removeLastObject];
// dismiss last controller
[controller
// the first controller in chain is dismissed with animation
dismissViewControllerAnimated: count == 1 ? YES : NO
// on completion call the block that calls this block recursively
completion: dismissCopy];
}
};
// this call dismisses all modal controllers
dismissController();
}