ios - 使用导航 Controller 时如何跳过 2 个 View

标签 ios iphone objective-c uinavigationcontroller

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

Xcode screenshot

(此处the fullscreen screenshot of the storyboard如上所示)

enter image description here

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

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

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

- (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;
}

并且可以看到,用户数据正在正常加载,但我不明白如何跳转到最后一个 View (尤其是因为大部分 UI 都在 Storyboard中定义)?

更新:我尝试按照 Tommy Alexander 的建议(谢谢!)在 AppDelegate.m 中使用以下代码(并且还为最后一个 View 分配了 Details StoryboardID):

- (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;
}

虽然最后一个 View (带有用户头像和详细信息的 UserViewController)似乎可以正常实例化,但我收到以下警告并且应用程序没有跳转到最后一个 View :

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: 当我将上面的代码移动到第一个 View 的 viewDidLoad 时(MasterViewController.m,用户可以在其中选择社交网络),然后我收到另一个警告:

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 的建议:

- (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;
}

最佳答案

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

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

  1. 为所有 Controller 分配 Storyboard ID,
  2. 从 Storyboard实例化所有三个 View Controller (这是轻量级的,只要您不在 Controller 的构造函数中进行大部分初始化工作)
  3. 按照 Storyboard中的顺序将它们放入数组中,
  4. 使用数组作为第一个参数调用 -[UINavigationController setViewControllers:]

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

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:],您会发现它会立即生效。

关于ios - 使用导航 Controller 时如何跳过 2 个 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21537773/

相关文章:

ios - -[UIView调整内容插入] : unrecognized selector sent to instance in ios 11

javascript - iOS Objective C - UIWebView 自动填充和执行

iphone - UISplitViewController - 有没有自定义实现的自动旋转方法?

iphone - 通过 Cocoa Touch 更改 iPhone 应用程序图标

ios - UIImagePickerController 之后 UIImage 的大小

javascript - 如何调用可以读取条形码并将数据返回到html的 native 应用程序

android - 如何在 react 导航中获取当前路线名称?

ios - Swift iOS 搜索栏加载自定义 View

objective-c - 设计用于下载和显示图像的异步过程

ios - FBAudienceNetwork : setting FBNativeAd into FBMediaView stacks the UI