在注销时重置故事板

我正在构build一个使用故事板的IOS 5.1 Web客户端应用程序。 我的一个动作是“注销”,在此期间,我想将根视图重置为由Storyboard的根视图创build的初始视图。 (login时,根据您的身份删除或添加一些查看项目;注销时,我想将它们重置为默认值,这是我在故事板中指定的值。

我意识到我可以以编程方式重置/重新添加所有的元素,但那么故事板有什么好处呢? 我认为有必要通过重新加载视图文件来回到原来的方式,对吧?

我发现以下方法适用于我。 请注意,我使用ARC,但不确定这是否对解决scheme有很大的影响。 首先,在应用程序委托类中,在application:didFinishLaunchingWithOptions:我使用以下代码行捕获inital Storyboard实例:

 _initalStoryboard = self.window.rootViewController.storyboard; 

(显然有一个实例variablesUIStoryboard* _initalStoryboard;

然后我在我的应用程序委托中定义了以下函数:

 - (void)resetWindowToInitialView { for (UIView* view in self.window.subviews) { [view removeFromSuperview]; } UIViewController* initialScene = [_initalStoryboard instantiateInitialViewController]; self.window.rootViewController = initialScene; } 

请注意,从window删除所有子视图的for循环。 UIWindow rootViewController文档指出:

如果窗口具有现有的视图层次结构,则在安装新视图之前删除旧视图。

不过,我没有发现这种情况…所以我明确地删除了现有的视图,然后分配一个新的rootViewController。 我还没有发现使用这种方法令人担忧的副作用或内存泄漏。 我绝不是UIKit的魔法专家,所以我build议你testing一下testing并重新testing这个解决scheme,如果你打算自己使用的话。 干杯

如果您使用基于NavController的结构,以下对我很有用:

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

您必须将“故事板ID”“login”分配给您的loginVC才能使其工作。

如果我使用基于UISplitViewController的结构(在iOS 8+上testing),以下工作适用于我:

从项目常规 – > 部署信息中删除故事板,所以下拉菜单如下所示,您必须在代码中configuration故事板。

部署信息空主接口

AppDelegate.m某处

 - (void)setupViewControllers { // check for thread, as this method might be called by other (eg 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:调用此函数application:didFinishLaunchingWithOptions:作为首次设置

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // some code... [self setupViewControllers]; // Optional: add splash view (eg [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() } }