2012-04-23 16 views
20

Я создаю приложение IOS 5.1 для веб-клиентов, использующее раскадровку. Одним из моих действий является «выход из системы», во время которого я хочу сбросить свой корневой режим в исходное представление, созданное корневым представлением раскадровки. (Когда вы входите в систему, некоторые элементы просмотра удаляются или добавляются на основе того, кто вы есть, а когда вы выходите из системы, я хочу сбросить их до значений по умолчанию, которые я указал в раскадровке.)Сбрасывание раскадровки при выходе из системы

Я понимаю что я мог бы программно сбросить/повторно добавить все элементы, но тогда какая польза от раскадровки? Я полагаю, что есть способ вернуться к квадрату, перезагрузив файл вида, верно?

+0

Вы когда-нибудь это выясняли? У меня точно такая же потребность в этом ... –

ответ

28

Я нашел для меня следующий подход. Обратите внимание, что я использую ARC, не уверен, что это имеет большое значение для решения. Во-первых, в классе делегата приложения, в application:didFinishLaunchingWithOptions: я захватить щёток раскадровки экземпляр с помощью следующей строки кода:

_initalStoryboard = self.window.rootViewController.storyboard; 

(Очевидно, есть экземпляр переменной UIStoryboard* _initalStoryboard;)

Тогда я следующая функция определена в моем приложении делегат:

- (void)resetWindowToInitialView 
{ 
    for (UIView* view in self.window.subviews) 
    { 
     [view removeFromSuperview]; 
    } 

    UIViewController* initialScene = [_initalStoryboard instantiateInitialViewController]; 
    self.window.rootViewController = initialScene; 
} 

Пожалуйста, обратите внимание, что для в цикле, который удаляет все подвидов из window. Документация UIWindow RootViewController гласит:

Если окно имеет существующую иерархию вида, старые взгляды удален до того, как новые установлены.

Однако я не нашел, что это так ... поэтому я сам удаляю существующие представления, прежде чем назначать новый rootViewController. Используя этот метод, я не обнаружил никаких побочных эффектов или утечек памяти. Я никоим образом не специалист по магии UIKit, поэтому я бы предложил вам протестировать тест и протестировать это решение, если вы планируете использовать его самостоятельно. Приветствия

+0

Я хотел попробовать, но на самом деле не показывать, как обращаться к функции с контроллера при нажатии кнопки. – gdubs

+2

Проверьте этот вопрос: http://stackoverflow.com/questions/1184146/getting-a-reference-to-the-uiapplication-delegate Он показывает, как вы можете получить ссылку на делегата вашего приложения - в вашем случае вы будете использовать это в контроллере представления вашей сцены. Итак, у вашего обработчика касания у вас будет что-то вроде: MyApplicationDelegate * appDelegate = (MyApplicationDelegate *) [[UIApplication sharedApplication] delegate]; [appDelegate resetWindowToInitialView]; –

+2

спасибо босс .... – gdubs

1

Следующая отлично работает для меня, если вы используете NavController на основе структуру:

UIWindow *window = [[UIApplication sharedApplication].windows firstObject]; 
UINavigationController *navController = (UINavigationController *)window.rootViewController; 
UIViewController *vc = [navController.storyboard instantiateViewControllerWithIdentifier:@"Login"]; 
navController.viewControllers = @[vc]; 

Вы должны назначить раскадровки ID «Login» в вашем Вход VC для того, чтобы это работало.

0

Следующих работ для меня, если я использую UISplitViewController -А структуру (испытанных на прошивке 8+):

Удалить Раскадровка из проектов Общих ->развертывания Info, поэтому выпадающие выглядят ниже, и вам нужно настроить раскадровку в коде.

Deployment Info Empty Main Interface

Где-то в AppDelegate.m

- (void)setupViewControllers 
{ 
    // check for thread, as this method might be called by other (e.g. logout) logic 
    if ([NSThread currentThread] != [NSThread mainThread]) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self setupViewControllers]; 
     }); 
     return; 
    } 

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 
    UIViewController *vc =[storyboard instantiateInitialViewController]; 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.window.rootViewController = vc; 

    // configure split vc 
    // Note: I reference split vc for my own purpose, but it is your mater of choice 
    self.splitViewController = (UISplitViewController *)self.window.rootViewController; 
    self.splitViewController.delegate = self; 
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; 
    self.splitViewController.preferredPrimaryColumnWidthFraction = 0.5; 

    [self.window makeKeyAndVisible]; 
} 

Чтобы избежать кода дубликатов, вызовите эту функцию из application:didFinishLaunchingWithOptions: как установки первого времени

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    // some code... 
    [self setupViewControllers]; 
    // Optional: add splash view (e.g. [self addSplashView];) 
    // some code... 
} 

Внутри контроллера представления вы готовы пользовательский интерфейс пользователя, удалите всплеск.Например (в Swift):

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 

    if !AppSession.currentSession().isLoggedIn() { 
     presentLoginViewController(false, completion: {()->Void in 
      self.removeSplash() 
     }) 
    } 
    else { 
     removeSplash() 
    } 

    // some code... 
} 

private func removeSplash() { 
    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate { 
     appDelegate.removeSplashView() 
    } 
} 
Смежные вопросы