Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS:从任意位置返回根视图控制器_Ios_Objective C_Iphone - Fatal编程技术网

iOS:从任意位置返回根视图控制器

iOS:从任意位置返回根视图控制器,ios,objective-c,iphone,Ios,Objective C,Iphone,我正在编写一个需要服务器登录的iPhone应用程序。应用程序的根视图控制器检查用户是否登录,并有条件地将用户发送到两个情节提要(登录或主应用程序)之一。根控制器不是UINavigationController(我见过的解决这个问题的许多解决方案都假设它是)。如果用户在服务器上注销(超时等),服务器请求将返回一个HTTP 401,我在web请求代码中截获它。。。我如何使它将用户反弹回登录屏幕和/或根视图控制器?我在StackOverflow和互联网上的其他地方搜索了几个小时,却找不到答案。我尝试了

我正在编写一个需要服务器登录的iPhone应用程序。应用程序的根视图控制器检查用户是否登录,并有条件地将用户发送到两个情节提要(登录或主应用程序)之一。根控制器不是UINavigationController(我见过的解决这个问题的许多解决方案都假设它是)。如果用户在服务器上注销(超时等),服务器请求将返回一个HTTP 401,我在web请求代码中截获它。。。我如何使它将用户反弹回登录屏幕和/或根视图控制器?我在StackOverflow和互联网上的其他地方搜索了几个小时,却找不到答案。我尝试了一个展开序列,它似乎被正确地调用(没有错误),但它实际上并没有展开到根视图控制器,可能是因为我直接在根视图控制器上调用它,根视图控制器是我的web请求类中唯一可见的。有什么想法吗

以下是我的应用程序流程:

+-------------------+ +--------------------------> | | |RootViewController | | +----------+UIViewController +------+ | | +-------------------+ | | | | | +-------v---------+ +----+----v-----------------+ | |Login storyboard | |SWRevealViewController | | |2 Views | |see note | | +-------+---------+ +---+-------------------+---+ | | | | | | | | +---------------+ +----------v-------+ +----v--------------------------------+ | Drawer | | Main Storyboard | | UIViewController | | Starts with UINavigationController | +------------------+ | | +-------------------------------------+ +-------------------+ +--------------------------> | || RootViewController | |++-----------+UIViewController++ | | +-------------------+ | | | | |+----v------++----v------+ ||登录故事板| | SWRevealViewController | || 2视图| |见注| | +-------+---------+ +---+-------------------+---+ | | | | | | | | +---------------++--v-------++--v--------------------------------+ |抽屉| |主情节提要| |UIViewController | |以UINavigationController开头| +------------------+ | | +-------------------------------------+
这是一种奇怪的野兽。。。它同时显示两个UIViewController,一个在另一个前面,后面的一个像“抽屉”一样,这样前面的一个可以滑到一边来访问它。

在RootViewController
viewDidLoad
中,订阅注销通知。在
视图显示的同一类中,检查用户的登录状态。如果用户需要登录,请在LoginViewController上显示ViewController
,否则显示SWRevealController

-(void)userDidLogout {
    [self dismissViewControllerAnimated:YES completion:nil];
 }
在通知处理程序中,如果用户已失去登录状态,只需执行以下操作:

[self dismissViewControllerAnimated:YES];

当在根vc(self)上调用Disclose时,它不关心上面是什么视图控制器,也不关心中间有多少视图控制器,它会删除所有内容以显示调用它的vc。根vc将有其
视图显示
**fire,您构建该视图是为了根据登录状态执行正确操作。

在登录视图控制器中,您可以使用本地通知中心添加一个侦听器

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDidLogout:) name:@"UserDidLogoutNotificationName" object:nil];
在通知引用的方法中,关闭视图控制器

-(void)userDidLogout {
    [self dismissViewControllerAnimated:YES completion:nil];
 }
无论何时你想注销,只要打电话就可以了,你应该会弹出你的注销屏幕

[[NSNotificationCenter defaultCenter]postNotification:@"UserDidLogoutNotificationName"]
根据您的图表,我不会考虑返回到注销屏幕,而是弹出所有的ViewController,直到它显示出来。

正如我在一个on中所指出的,我可能遗漏了一个重要的细节。我将登录屏幕和主屏幕显示为根视图控制器的子视图控制器。经过一段时间的思考,我意识到解决方案是交换子视图控制器。随后进行了大量的研究和咬牙切齿,我找到了一个似乎有效的解决方案

我最初从根视图控制器的
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处理程序的委托。谢谢你,丹;虽然你的回答没有直接解决我的问题,但它确实让我以一种新的方式思考这个问题,从而找到了答案

也许可以使用nsnotification center使用观察者以模式显示登录控制器?请提供有关视图控制器层次结构的更多详细信息。@Yanchi我不太了解notification center,但我不知道如何显示它(以模式或其他方式)吗从通知处理程序?@robmayoff我添加了一个视图控制器和故事板流程图(使用我刚刚发现的漂亮工具asciflow.com创建),这是一个有趣的可能性。。。当前,在我的根视图控制器中,我通过
addChildViewController
addSubview
显示登录或显示视图,因为当我使用
presentViewController
尝试时,根视图控制器出现了一个空白屏幕(甚至从vi调用)