在注销时重置故事板
我正在构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() } }