首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在使用导航控制器时跳过两个视图

如何在使用导航控制器时跳过两个视图
EN

Stack Overflow用户
提问于 2014-02-04 05:06:44
回答 10查看 9K关注 0票数 18

在Xcode5.0.2中,我创建了一个iPhone应用程序(完整的应用程序code is on GitHub,请运行pod install一次-适用于SDWebImage),它显示社交网络(Facebook、Google+等)的列表,然后-在另一个视图中- UIWebView显示OAuth2网页,然后是第三个视图,其中包含用户头像和详细信息(名、姓等):

(这里是上面显示的the fullscreen screenshot of the storyboard )

在最后一个视图中显示用户头像和详细信息之前,我将用户数据保存到NSUserDefaults

我的问题是:当用户下一次启动应用程序时,NSUserDefaults中已经有用户数据-我如何跳过前2个视图并显示(没有任何动画)包含这些用户详细信息的最后一个视图?

我已将以下代码放入AppDelegate.m

代码语言:javascript
复制
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *key = [defaults objectForKey:@"key"];
    User *user = [User loadForKey:key];

    if (user) {
        UINavigationController *nc = (UINavigationController*)self.window.rootViewController;
        // XXX how to load the last view here? XXX
    }

    return YES;
}

可以看到,用户数据正在正常加载,但我不知道如何跳转到最后一个视图(例如,因为大多数UI都是在故事板中定义的)?

更新:我已经尝试了汤米·亚历山大的建议(谢谢!)使用AppDelegate.m中的以下代码(还将Details StoryboardID分配给最后一个视图):

代码语言:javascript
复制
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *key = [defaults objectForKey:@"key"];
    User *user = [User loadForKey:key];

    if (user) {
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        UIViewController *uvc = [storyboard instantiateViewControllerWithIdentifier:@"Details"];
        NSLog(@"XXX uvc=%@ user=%@", uvc, user);
        [self.window.rootViewController presentViewController:uvc animated:YES completion:nil];
    }

    return YES;
}

虽然最后一个视图(带有用户头像和详细信息的UserViewController )似乎被实例化了,但我得到了以下警告,应用程序没有跳到最后一个视图:

代码语言:javascript
复制
MyAuth[3917:70b] XXX uvc=<UserViewController: 0x8acbac0> user=
VK
59751265
Alexander
Farber
1945522
http://cs319319.vk.me/v319319265/b7df/TnyKeffL_mU.jpg
0
MyAuth[3917:70b] Warning: Attempt to present <UserViewController: 0x8acbac0> on <UINavigationController: 0x8bb3a30> whose view is not in the window hierarchy!

更新2:当我将上面的代码移动到第一个视图的viewDidLoad ( MasterViewController.m,用户可以在其中选择社交网络)时,我收到另一个警告:

代码语言:javascript
复制
MyAuth[1358:70b] XXX uvc=<UserViewController: 0x8a97430> user=
FB
597287941
Alexander
Farber
Bochum, Germany
http://graph.facebook.com/597287941/picture?type=large
0
MyAuth[1358:70b] Unbalanced calls to begin/end appearance transitions for <UINavigationController: 0x8a893e0>.

更新3:感谢您的宝贵答案!我最终使用了Leonty Deriglazov的建议:

代码语言:javascript
复制
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *vc1 = [storyboard instantiateViewControllerWithIdentifier:@"Master"];
    //UIViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:@"Login"];
    UIViewController *vc3 = [storyboard instantiateViewControllerWithIdentifier:@"User"];

    User *user = [User load];
    NSArray *controllers = (user ? @[vc1, vc3] : @[vc1]);

    UINavigationController *nc = (UINavigationController *)self.window.rootViewController;
    [nc setViewControllers:controllers];

    return YES;
}
EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2014-02-06 23:54:35

简而言之,最直接的解决方案是使用-[UINavigationController setViewControllers:animated:]

您需要执行以下操作才能实现您想要的结果:

  1. 将情节提要ID分配给所有控制器,
  2. 从情节提要中实例化所有三个视图控制器(这是轻量级的,只要您不在控制器的
  3. 中执行大多数初始化工作,将它们按照在情节提要中的相同顺序放入一个数组中,
  4. 调用-[UINavigationController setViewControllers:],并将该数组作为第一个参数。

就这样。您的-[AppDelegate application:didFinishLaunchingWithOptions:]中的代码可能如下所示(当然,在检查您的跳过条件之后):

代码语言:javascript
复制
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc1 = [storyboard instantiateViewControllerWithIdentifier:@"MyAuth"]; //if you assigned this ID is storyboard
UIViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:@"Login"];  //if you assigned this ID is storyboard
UIViewController *vc3 = [storyboard instantiateViewControllerWithIdentifier:@"Details"];
NSArray *controllers = @[vc1, vc2, vc3];
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
[navController setViewControllers:controllers];

如果您只将其粘贴到-[AppDelegate application:didFinishLaunchingWithOptions:],您将看到它立即生效。

票数 15
EN

Stack Overflow用户

发布于 2014-02-06 20:33:40

打破视图层次结构总是会产生奇怪的行为。

通过使用下面提到的方法,用户将不会注意到显示了LoginViewController,然后我们已将其推送到详细信息屏幕。

这种方法对我来说总是有效的。

LoginViewController.m文件中的

代码语言:javascript
复制
- (void)viewDidLoad
{

if (user) {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UserViewController *userViewController = [storyboard instantiateViewControllerWithIdentifier:@"Details"];


[self.navigationController pushViewController:listViewVC animated:YES];

    }
}

UserViewController.m文件中的

代码语言:javascript
复制
-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];

if (user) {

    self.navigationItem.hidesBackButton = YES;

}

}
票数 4
EN

Stack Overflow用户

发布于 2014-02-06 19:17:32

我认为你的问题从你的初始Storyboard设置开始。我会使用类似于下图的东西。

我会让User View controller成为我的根视图控制器,并以带或不带动画的方式呈现登录视图控制器。

一旦登录成功,就可以很方便地关闭视图控制器。如果用户稍后注销,您只需再次显示登录视图控制器。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21537773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档