Как отменить 2 Modal View Controllers в последовательности?

У меня есть 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?

Ответ 1

Попробуйте использовать следующий код в B (сразу после увольнения C, как вы уже это сделали):

[self.parentViewController dismissModalViewControllerAnimated:YES];

ВАЖНО:
Не делайте ничего в методе после этой строки.
Этот контроллер вида (B), вероятно, будет освобожден и освобожден...

UPDATE:
Начиная с iOS7, метод выше устарел.
Вместо этого используйте следующий метод:

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

Ответ 2

Просто выяснилось, что вам нужно использовать presentingViewController в iOS 5.

[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];

A → B → C

Запуск вышеуказанного кода в модальном C приведет вас обратно к A

Ответ 3

Это сработало для меня очень просто

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

Объяснение:

Если вы вызываете увольнение на C, он может удалить только C. Если вы вызываете увольнение на B, он сделает правильную вещь: удалите самый верхний контроллер модального представления. Поэтому первый вызов удаляет C (без анимации). Второй вызов удаляет B.

Самый простой способ получить доступ к контроллеру просмотра B из C - использовать переменную presentingViewController.

Ответ 4

В B. Put:

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

Выполнять только одну анимацию.

Ответ 5

Проверьте это для быстрого:

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

Ответ 6

В быстрых 4

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

Ответ 7

Вам нужна только одна команда увольнения. Просто отпустите B, а затем C уйдет с ним.

Ответ 8

Это сработало для меня:

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

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

Ответ 9

Я прочитал все темы, и я не нашел правильного ответа. Если вы отклоните 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, и все это выглядит намного приятнее!

Ответ 10

Контроллер навигации имеет свойство viewControllers, которое представляет собой массив - вы можете установить его на новый массив за вычетом двух контроллеров представления, которые вы хотите удалить.

Ответ 11

Вдохновленный решением Albertos, я создал метод делегата в B с блоком, чтобы показать результат удаления учетной записи:

#pragma - mark - AddAccountViewControllerDelegate Methods

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

Ответ 12

Я столкнулся с той же проблемой, и лучшим решением было создание "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-view, когда я вызываю Далее, в моем модальном режиме B, когда я вызываю другое модальное представление C, полагая, что для segue:

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

Наконец, в моем файле c.h, давайте подготовиться к делегату:

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

И в моем файле cm, я просто скажу, что мой viewDelegate отклонил мой modal view controller и сам:

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

И что это.

Надеюсь, это сработает для всех вас.

Ответ 13

Вот как можно уволить больше одного модального контроллера, используя цикл повторения:

Swift 3

// 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)

Ответ 14

Я знаю, что этот ответ может показаться излишним, но приведенное ниже утверждение должно иметь смысл, и вы получите представление о том, как это работает.

Просто отклоните самый старый контроллер представления, и все другие более поздние контроллеры представления исчезнут с этим.

В случае 2 контроллеров представления:

Цель C:

[self.presentingViewController dismissViewControllerAnimated:true completion:nil]

Swift:

presentingViewController?.dismissViewControllerAnimated(true, completion: nil)

Ответ 15

Я нашел решение.

Вы можете поместить эти ViewControllers в отдельный NavigationController. И чем уволить NavigationController приведет к тому, что все эти ViewControllers уволить сразу.

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