web-dev-qa-db-ja.com

2つのモーダルビューコントローラーを連続して閉じる方法は?

私は2つのビューコントローラーをモーダルで表示しています。

A presents B which presents C.

Cを解任するときは、Bも解任したいと思います。しかし、これを行う方法はわかりません:

Cを却下:

[self dismissModalViewControllerAnimated:YES]
//[delegate dismissB] //this doesn't work either when i create a delegate pattern

今、私はBが残っています。BをCから解任するにはどうすればよいですか。

38
Sheehan Alam

Bで次のコードを使用してみてください(すでに行ったように、Cを閉じた直後):

[self.parentViewController dismissModalViewControllerAnimated:YES];

重要
この行の後のメソッドでは何もしないでください。
このビューコントローラ(B)はおそらく解放され、割り当て解除されます...

更新
iOS7以降、上記の方法は廃止されました。
代わりに次の方法を使用してください:

[self.parentViewController dismissViewControllerAnimated:YES completion:^{ /* do something when the animation is completed */ }];
8
Michael Kessler

IOS 5でpresentingViewControllerを使用する必要があることがわかりました。

[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];

A-> B-> C

上記のコードをモーダルCで実行すると、Aに戻ります

110
Andy Davies

これは私にとってはとても簡単でした

// Call inside View controller C    
self.presentingViewController?.dismissViewControllerAnimated(false, completion: nil)
self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)

説明:

Cでdismissを呼び出すと、Cしか削除できません。Bでdismissを呼び出すと、正しいことを実行します。最上位のモーダルビューコントローラーを削除します。したがって、最初の呼び出しでC(アニメーションなし)が削除されます。 2番目の呼び出しはBを削除します。

CからビューコントローラーBにアクセスする最も簡単な方法は、presentingViewController変数を使用することです。

14
n13

B.プット:

[self dismissModalViewControllerAnimated:NO];
[self dismissModalViewControllerAnimated:YES];

1つのアニメーションのみを実行します。

12

これをSwiftで確認します。

self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil);
6
Victor Rius

In Swift 4

self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil);

6
TheSwiftGuy77

すべてのトピックを読みましたが、適切な答えが見つかりませんでした。 Bを却下すると、Cはすぐに消えて奇妙な効果を生み出します。適切な方法は、Cを下からカスタムアニメーションを使用して子ビューコントローラとして提示することです。

   [b addChildViewController:c];
    c.view.frame = CGRectOffset(b.view.bounds, 0, b.view.bounds.size.height);
    [b.view addSubview:c.view];
    [c didMoveToParentViewController:b];

    [UIView animateWithDuration:0.5 animations:^{
        c.view.frame = CGRectOffset(c.view.frame, 0, -b.view.bounds.size.height);
    } completion:^(BOOL finished) {

    }];

そして、あなたは単にBを却下し、それはすべてはるかに良く見えます!

2
Rudolf J

これは私のために働きました:

// Swift
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)

// Objective-C
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
2
Nagra

Dismissコマンドは1つだけ必要です。 Bを却下すると、Cはそれを廃止します。

1
Dancreek

Albertosソリューションに触発されて、アカウントを削除した結果を表示するブロックを含むデリゲートメソッドをBに作成しました。

#pragma - mark - AddAccountViewControllerDelegate Methods

- (void) dismissToSettings {
    [self dismissModalViewControllerAnimated:NO];
    [self dismissViewControllerAnimated:YES completion:^(void){[DKMessage showMessage:LS(@"Account was successfully created")];}];
}
0
Denis Kutlubaev

繰り返しサイクルを使用して複数のモーダルビューコントローラーを閉じる方法は次のとおりです。

Swift

// In this example code will go throw all presenting view controllers and 
// when finds it then dismisses all modals.
var splitViewController: UIViewController? = self

repeat {
    splitViewController = splitViewController?.presentingViewController
} while (!(splitViewController is UISplitViewController) && (splitViewController != nil))

splitViewController?.dismiss(animated: true, completion: nil)
0
Ramis

この答えは冗長に感じるかもしれませんが、以下のステートメントは理にかなっているはずであり、これがどのように機能するかを理解できます。

最も古いView Controllerを閉じるだけで、それ以降のすべてのView Controllerはこれを廃止します。

2つのView Controllerの場合:

目標C:

[self.presentingViewController dismissViewControllerAnimated:true completion:nil]

迅速:

presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
0
Shobhit C

私は同じ問題に直面し、より良い解決策は次のように「DismissViewProtocol」を作成することでした:

ファイル:DismissViewProtocol.h

@protocol DismissViewProtocol <NSObject>
-(void)dismissView:(id)sender;
@end

私のBモーダルビューで、デリゲートメソッドの応答を見てみましょう。

私のb.hファイル:

#import "DismissViewProtocol.h"
@interface B-Modal : UIViewController <DismissViewProtocol>
...
@end

私のb.mファイル:

-(void) dismissView:(id)sender
{
 [((UIViewController *) sender) dismissModalViewControllerAnimated:NO];
 [self dismissModalViewControllerAnimated:YES];
}

同じBビューコントローラーで、Nextを呼び出すと、Bモーダルビューで、他のモーダルビューCを呼び出すと、次のようになります。

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    ((C-ViewController *)segue.destinationViewController).viewDelegate=self;
}

最後に、私のc.hファイルで、デリゲートの準備をしましょう。

@property(nonatomic, weak) id <DismissViewProtocol> viewDelegate;

そして、私のc.mファイルで、自分のモーダルビューコントローラーとそれ自体を閉じるようにviewDelegateに指示します。

-(void)closeBothViewControls
{
       [self.viewDelegate dismissView:self];
}

以上です。

それがあなた方全員のために働くことを願っています。

0
Anibal Itriago

解決策を見つけました。

これらをViewControllersを個別のNavigationControllerに入れることができます。そしてNavigationControllerを却下すると、これらすべてのViewControllersが一度に却下されます。

https://Gist.github.com/ufo22940268/2949fdf59c9860292f263ebb1e8036d7

0
Frank Cheng

ナビゲーションコントローラには、配列である「viewControllers」プロパティがあります。これを、削除する2つのビューコントローラを差し引いた新しい配列に設定できます。