Скрыть все контроллеры модального вида - PullRequest
9 голосов
/ 29 декабря 2011

У меня есть вид входа в систему, представленный как ModelViewController, и поверх него вид реестра, представленный как NavigationControlloer:

Вход в систему (ModelViewController) ----> Регистрация (NavigationController)

Я представляю представление «Регистрация» (CreateAccount) при просмотре входа в систему следующим образом:

createAccount= [[CreateAccount alloc] initWithNibName:@"CreateAccount" bundle:nil];

navController = [[UINavigationController alloc] initWithRootViewController:createAccount];

UIBarButtonItem *cancelButtun=[[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(HideMe)];

UIBarButtonItem *registerButtun=[[UIBarButtonItem alloc]initWithTitle:@"Register" style:UIBarButtonItemStyleBordered target:self action:@selector(Register)];

createAccount.navigationItem.leftBarButtonItem = cancelButtun;
createAccount.navigationItem.rightBarButtonItem=registerButtun;
createAccount.title=@"Create Account";

[self presentModalViewController:navController animated:YES];

контроллер входа имеет NSURLConnectionDelegate для входа в систему и регистрации.когда регистрация заканчивается, я просто вызываю

[self dismissModalViewControllerAnimated:YES];

, который отклоняет только представление регистрации.

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

Ответы [ 7 ]

23 голосов
/ 29 декабря 2011

Вызов dismissModalViewController вызовет, если текущий контроллер представления не представил модальные контроллеры, вместо этого вызовет метод для его родителя.Вызов метода на контроллере вида приведет к удалению всех представленных контроллеров модального представления этому контроллеру.Для иллюстрации:

Если у вас есть три контроллера представления: vc1, vc2 и vc3, а vc1 - основной / используемый в настоящее время контроллер представления.

  1. В vc1 вы представляете модальный vc2,Затем в vc2 вы вызываете dismiss, поскольку модальные vcs не представлены из vc2, сообщение dismiss передается родителю (vc1), который отклоняет vc2, и вы возвращаетесь в vc1.

  2. В vc1 вы представляете модальный vc2, затем из vc2 присутствует модальный vc3.Вызов dismiss в vc3 отправит сообщение его родителю (vc2), который отклонит vc3.Чтобы закрыть vc2 и vc3 одновременно, вам нужно вызвать dismiss в vc1, это приведет к отклонению всех (обоих) контроллеров модального представления.Если отклонить анимированный, будет анимирован только первый.

Один из лучших способов решить эту проблему - использовать универсальный контроллер навигации.то есть вместо того, чтобы использовать modalViews изначально для представления вида входа в систему, используйте navigationViewcontroller там же.Если вам нужно представить страницу регистрации.Подтолкните это мнение.Если вам нужно перейти к начальному виду (т. Е. Кроме loginView или registrationView), используйте метод popToRootViewControllerAnimated в navigationViewcontroller.

20 голосов
/ 29 декабря 2011

Проверьте мой ответ на похожий вопрос здесь: Увольнение ModalViewController из ModalViewController

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

Редактировать: Чтобы отклонить модальное представление, представленное поверх другого модального представления, у вас естьвызвать dismissModalViewControllerAnimated: на родительском элементе родителя.

iOS <5.0 </p>

[[[self parentViewController] parentViewController] dismissModalViewControllerAnimated:YES];

iOS 5.0+ (необходимо изменить все ссылки на parentViewController для представления ViewController)

[[[self presentingViewController] presentingViewController] dismissModalViewControllerAnimated:YES];
1 голос
/ 29 декабря 2011

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

Сначала объявите протокол и свойство делегата в контроллере представления регистрации.

@protocol CreateAccountDelegate;

@interface CreateAccount : UIViewController

@property (nonatomic, assign) id <CreateAccountDelegate> delegate;

@end

@protocol CreateAccountDelegate <NSObject>

- (void)createAccountViewControllerDidFinish:(CreateAccount *)controller;

@end

Затем сделайте контроллер представления входа в систему делегатом контроллера регистрации.

createAccount = [[CreateAccount alloc] initWithNibName:@"CreateAccount" bundle:nil];
createAccount.delegate = self;

И внедрите -createAccountViewControllerDidFinish:

- (void)createAccountViewControllerDidFinish:(CreateAccount *)controller
{
    [self dismissModalViewControllerAnimated:YES];
}

Наконец, когда вы увольняетесь из контроллера регистрации, отправьте сообщение делегату, чтобы сообщить об этом в случае вашего скорого увольнения.

[self.delegate createAccountViewControllerDidFinish:self];
[self dismissModalViewControllerAnimated:YES];

Теперь , сказав все это.Могу ли я предложить изменение вашего дизайна?Я бы представил контроллер вида входа в систему как часть контроллера навигации с самого начала.Затем, если пользователь решит зарегистрироваться, просто передайте представление регистрации на контроллер.Таким образом, независимо от того, откуда вы отказываетесь, вам нужно будет только отклонить основной навигационный контроллер.

0 голосов
/ 31 мая 2017
[[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissViewControllerAnimated:true completion:nil];

Отключить все контроллеры, кроме RootViewController ..

0 голосов
/ 01 апреля 2014
while(self.presentedViewController)
        [self.presentedViewController dismissViewControllerAnimated:NO completion:nil];

Работал, чтобы закрыть все в iOS 7

0 голосов
/ 01 июля 2013

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

-(void)dismissModalViews
{
    if (self.window.rootViewController.presentedViewController) {
        [self.window.rootViewController.presentedViewController dismissViewControllerAnimated:NO completion:nil];
        [self performSelector:@selector(dismissModalViews) withObject:nil afterDelay:0.5];
    }
}
0 голосов
/ 29 декабря 2011

dismissModalViewControllerAnimated: отклоняет все контроллеры модального представления, представленные сверху отправителя. Чтобы закрыть обратно к контроллеру представления, который представил контроллер входа, сохраните ссылку на него и отклоните следующим образом:

[loginController dismissModalViewController:animated]

Это грубая сила, способ сделать это. В моем приложении, где я делал что-то подобное, я публикую различные уведомления, соответствующие состоянию сеанса (например, вход в систему), и мой контроллер входа в систему наблюдает за этими уведомлениями и соответствующим образом удаляет себя.

...