如何根据 iOS 中的两个条件从 AppDelegate 呈现两个不同的 ViewController?

Posted

技术标签:

【中文标题】如何根据 iOS 中的两个条件从 AppDelegate 呈现两个不同的 ViewController?【英文标题】:How to present two different ViewControllers from AppDelegate based on two conditions in iOS? 【发布时间】:2013-12-12 07:53:59 【问题描述】:

当应用程序从最小化恢复时,我想从 AppDelegate 呈现两个 ViewController。 我已经使用applicationWillEnterForeground: 函数来呈现 ViewControllers。但是,当我使用以下代码运行应用程序时,它会崩溃并显示错误:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target <ViewController: 0x1566a420>.' 而且我使用 storyBoards 来呈现 ViewControllers 而不是 nib 文件。 请帮助我解决这个问题,因为我哪里出错了。一周以来我一直在为此苦苦挣扎。

- (void)applicationWillEnterForeground:(UIApplication *)application

    if(ConditionOne)
    
         [self.window.rootViewController presentViewController:[self getMyFilesActivityView] animated:YES completion:nil];
         [self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
    
    else if(ConditionTwo)
    
         [self.window.rootViewController presentViewController:[self getPasswordActivityView] animated:YES completion:nil];
         [self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
    

-(MyFilesViewController *)getMyFilesActivityView

    if(self.myFiles== nil)
    
        self.myFiles = [[MyFilesViewController alloc]init];
        myFiles = [self.storyboard instantiateViewControllerWithIdentifier:@"MyFilesID"];
    
    return self.myFiles;

-(PasswordEnterViewController *)getPasswordActivityView

    if(self.passwordEnter== nil)
    
        self.passwordEnter = [[PasswordEnterViewController alloc]init];
        passwordEnter = [self.storyboard instantiateViewControllerWithIdentifier:@"PasswordEnterID"];
    
    return self.passwordEnter;

【问题讨论】:

【参考方案1】:

这里有些地方不对。

首先,当你运行这段代码时:

[self.window.rootViewController presentViewController:[self getMyFilesActivityView] animated:YES completion:nil];
[self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];

它将首先呈现视图控制器,然后直接将其关闭,这不是您想要的。您想在显示另一个视图控制器之前关闭旧视图控制器吗?那么你应该这样做:

[self.window.rootViewController dismissViewControllerAnimated:YES completion:^
    [self.window.rootViewController presentViewController:[self getViewController] animated:YES completion:nil];
];

另外,你的 getter 有一些非常错误的地方:

    self.passwordEnter = [[PasswordEnterViewController alloc]init];
    passwordEnter = [self.storyboard instantiateViewControllerWithIdentifier:@"PasswordEnterID"];

第一行分配一个 PasswordEnterViewController,第二行做同样的事情。在这种情况下,第一行不会做任何事情(如果 self.passwordEnter 和 passwordEnter 甚至是同一个变量,那就很不清楚了。)

这就是你的 setter 的样子:

- (PasswordEnterViewController *)passwordEnter

    if(_passwordEnter == nil)
    
        self.passwordEnter = [self.storyboard instantiateViewControllerWithIdentifier:@"PasswordEnterID"];
    
    return _passwordEnter;

您的 passwordEnter 属性应如下所示:

@property (nonatomic, strong) UIViewController *passwordEnter;

此外,请删除您可能正在进行的任何 @synthesize 调用,因为您似乎覆盖了自动合成器,这使得您的代码难以遵循。

当你的 setter 和 property 看起来像上面那样时,你可以简单地使用下面的代码来呈现它:

[self.window.rootViewController presentViewController:self.passwordEnter animated:YES completion:nil];

【讨论】:

我尝试了和你说的一样的方法,但它仍然崩溃并出现同样的错误。 那么要么你的故事板标识符是错误的,要么你实现了错误的吸气剂。无论哪种情况,getter 都必须返回 nil。尝试在此处设置断点并找出原因 我已将情节提要也声明为属性。那么这会影响代码吗?? 是的,这可能是问题所在。不要声明情节提要! self.storyboard 是一个视图控制器属性,它获取运行代码的视图控制器从中加载的故事板。相反,您可以使用 [[UIStoryboard storyboardWithName:@"StoryboardName"] instantiateView... 等 如果我不声明情节提要,那么它会显示错误为“选择器实例化ViewControllerWithIdentifier 没有已知类:

以上是关于如何根据 iOS 中的两个条件从 AppDelegate 呈现两个不同的 ViewController?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 Oracle 表格 6i 中的某些条件在两个 LOV 之间进行选择

如何根据不同的分组条件得到两个数量列的总和?

如何根据其他列中的条件从某个 ID 中选择所有值?

如何根据 GraphQL (NestJS) 中的条件发送不同的订阅响应?

如何根据条件配置Angular 5中的app-routing.module来加载两个子路由模块中的一个或另一个?

从 json 数据渲染表格后,如何根据 Datatables.js 中的条件为每个单元格着色? [复制]