2014-09-15 3 views
0

Я пишу iPhone-приложение, требующее входа в систему. Контроллер корневого представления для приложения проверяет, зарегистрирован ли пользователь и условно отправляет пользователя на одну из двух раскадровки (логин или основное приложение). Корневой контроллер не является UINavigationController (многие из решений, которые я видел с этой проблемой, предполагают, что это так). Если пользователь выйдет из системы на сервере (тайм-аут и т. Д.), Запросы сервера вернут HTTP 401, который я перехватываю в своем коде веб-запроса ... как я могу заставить этот отказ вернуть пользователя на экран входа в систему и/или контроллер корневого представления? Я часами просматривал StackOverflow и остальную часть Интернета, и я не могу найти ответ. Я попытался отключить Segue, и, похоже, он вызван правильно (без ошибок), но на самом деле он не отключается от контроллера корневого представления, возможно, потому, что я вызываю его непосредственно на контроллере корневого представления, который является только один из видимых из моего класса веб-запросов. Есть предположения?iOS: вернитесь в контроллер корневого представления из любого места

Вот мое приложение поток:

       +-------------------+              
+-------------------------->     |              
|       |RootViewController |              
|    +----------+UIViewController +------+            
|    |   +-------------------+  |            
|    |          |            
|  +-------v---------+     +----+----v-----------------+        
|  |Login storyboard |     |SWRevealViewController  |        
|  |2 Views   |     |see note     |        
|  +-------+---------+     +---+-------------------+---+        
|    |        |     |         
|    |        |     |         
+---------------+     +----------v-------+  +----v--------------------------------+ 
            | Drawer   |  | Main Storyboard     | 
            | UIViewController |  | Starts with UINavigationController | 
            +------------------+  |          | 
                   +-------------------------------------+ 

SWRevealViewController что-то странного зверя ... он показывает две UIViewControllers одновременно, один перед другим, с за один действует как «ящик» , так что передняя часть может быть сдвинута в сторону, чтобы получить к ней доступ.

+0

Может быть представлен контроллер входа в систему с использованием центра nsnotification с помощью наблюдателей? – Yanchi

+0

Дайте нам более подробную информацию о вашей иерархии диспетчера просмотров. –

+0

@ Янчи Я не очень хорошо понимаю центр уведомлений, но разве у меня не было бы такой же проблемы с вычислением _how_, чтобы отобразить его (по тексту или иначе) из обработчика уведомлений? – rmeador

ответ

0

Как я указал в comment на danh's answer, я, возможно, оставил важную деталь. Я представляю экран входа и главный экран в качестве контроллеров детского представления контроллера корневого представления. Обдумывая это некоторое время, я понял, что решение состоит в том, чтобы поменять контроллеры дочерних представлений. Последовали многочисленные исследования и скрежет зубов, и я пришел к решению, которое, похоже, работает надежно.

Я сначала показать экран (здесь главный экран) из моего корня вид диспетчерское viewDidLoad так:

[self addChildViewController:self.mainViewController]; 
[self.view addSubview:self.mainViewController.view]; 
[self.mainViewController didMoveToParentViewController:self]; 
[self.view layoutIfNeeded]; 

А потом, когда я хочу, чтобы перейти на экран входа в систему, я делаю это:

- (void)switchToLoginScreen 
{ 
    [self switchScreensFrom:self.mainViewController to:self.loginViewController]; 
} 

- (void)switchScreensFrom:(UIViewController *)fromViewController to:(UIViewController *)toViewController 
{ 
    [fromViewController willMoveToParentViewController:nil]; 
    [self addChildViewController:toViewController]; 

    [self transitionFromViewController:fromViewController 
         toViewController:toViewController 
           duration:0.25 
           options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve 
          animations:^{} 
          completion:^(BOOL finished){ 
           [fromViewController removeFromParentViewController]; 
           [toViewController didMoveToParentViewController:self]; 
          }]; 
} 

Переход в другую сторону работает аналогичным образом. Метод switchToLoginScreen вызывается из обработчика в моем делете приложения, который имеет доступ к контроллеру корневого представления через self.window.rootViewController. Делегат приложения подписывается как делегат для обработчика HTTP 401 при запуске приложения. Спасибо, дань; в то время как ваш ответ напрямую не решал мою проблему, мне стало легче подумать о проблеме по-новому, что привело меня к ответу!

2

В RootViewController viewDidLoad подпишитесь на уведомление о выходе из системы. В этом же классе в viewDidAppear проверьте состояние входа пользователя. Если пользователю требуется войти в систему, presentViewController на вашем LoginViewController, в противном случае появится SWRevealController.

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

[self dismissViewControllerAnimated:YES]; 

Отклонить, при вызове на корневой ОМ (самостоятельно), не все равно, что вид контроллера сверху или сколько есть между ними, он удаляет все, чтобы открыть vc, на котором он был вызван. У этого корня vc будет свой огонь viewDidAppear **, который вы построили для правильной работы на основе зарегистрированного состояния.

+0

Это интересная возможность ... В настоящее время в моем контроллере корневого представления я показываю логин или открывать представления через 'addChildViewController' и' addSubview', потому что, когда я попробовал его с 'presentViewController', было заметное отставание, показывающее пустой экран для контроллера корневого представления (даже вызываемого из viewDidLoad). Можете ли вы подумать, как это может повлиять на ваше предложение? – rmeador

+0

Мой плохой. Презентации могут происходить только в viewDidAppear или после. Но если вы представляете в viewDidAppear с анимированным = НЕТ, вы не должны видеть никакого запаздывания. Изменит мой ответ. – danh

0

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

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDidLogout:) name:@"UserDidLogoutNotificationName" object:nil]; 

уведомления В методе ваши ссылки уведомления, закрыть контроллер представления.

-(void)userDidLogout { 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

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

[[NSNotificationCenter defaultCenter]postNotification:@"UserDidLogoutNotificationName"] 

Основываясь на диаграмме, я бы не думать о переходе обратно к экрану выхода из системы, а popping все viewcontrollers, пока не будет обнаружено

Смежные вопросы