管理和解除iOS中的多视图控制器

时间:2012-08-17 19:53:38

标签: ios uiviewcontroller

我是iPhone的新手程序员。在开发我的第一个游戏/应用程序时,我为自己想出了一个问题(创建了一个问题)。我已经研究了这个并认为我已经看到了答案,但我不明白如何让它们适用于我的应用程序。

我有一个拥有一些视图控制器的游戏:欢迎,播放,高分,偏好和关于。我没有导航控制器或我知道的根控制器。编辑 - 我现在有一个rootview控制器 - 我将[self.window setRootViewController:viewController];添加到我的appDelegate.m文件

在欢迎屏幕/ viewcontroller中,我可以转到Play视图控制器,about视图控制器,高分视图控制器或prefs视图控制器。我想制作我现在负责的新控制器,以便我可以关闭Welcome视图控制器。事实上,每当我去一个视图控制器时,我希望能够从内存中解除任何其他视图控制器 - 特别是我刚刚来自的视图控制器。我可以从大多数视图控制器 大多数视图控件

我使用它来转到新的视图控制器:

- (IBAction)playGameAction:(id)sender {
    FlipTestViewController *myViewController = [[FlipTestViewController alloc]

   initWithNibName:@"FlipTestViewController" bundle:nil];

    [UIView beginAnimations:@"flipview" context:nil];
    [UIView setAnimationDuration:1];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft 
                           forView:self.view cache:YES];

    [self.view addSubview:myViewController.view];

    [UIView commitAnimations];
}

一旦我安全地进入FlipTestViewController(播放控制器),我该怎么办才能让WeclomeViewController运行?如何告诉新控制器它现在负责而其他控制器可以消失?我甚至问一个有意义的问题吗?请在回复时使用小词和具体示例!谢谢!

根据rdelmar的建议,我尝试添加一个调用来将RootvVewController更改为我的按钮代码 - 我用来启动新viewController的代码:

- (IBAction)playGameAction:(id)sender {
    FlipTestViewController *myViewController = [[FlipTestViewController alloc]
                                                      initWithNibName:@"FlipTestViewController"
                                                      bundle:nil];

    [UIApplication sharedApplication].delegate.window.rootViewController = myViewController;
    [UIView beginAnimations:@"flipview" context:nil];
    [UIView setAnimationDuration:1];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft 
                           forView:self.view cache:YES];

    [self.view addSubview:myViewController.view];

    [UIView commitAnimations];

}

果然,然后我查看评论,FlipTestViewController(我的Play控制器)是新的RootViewController。不幸的是,我得到一个空白的白色屏幕,没有任何类型的转换和日志消息告诉我,我的FlipTestViewController中的ViewDidDisappear正在以某种方式被调用。可能是因为欢迎屏幕仍然存在。或许内存管理问题?我应该把这个带到一个新问题吗?

我刚刚更改了main.xib文件的背景颜色,显然这是显示的屏幕(空白屏幕)。

3 个答案:

答案 0 :(得分:2)

要以模态方式呈现视图控制器,您可能需要尝试此方法:

- (IBAction)playGameAction:(id)sender {
    FlipTestViewController *myViewController = [[FlipTestViewController alloc] initWithNibName:@"FlipTestViewController" bundle:nil];

    myViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentViewController:myViewController animated:YES completion:nil];
}

这会将FlipTestViewController置于当前视图的顶部,并采用翻转过渡方式。

然后要关闭视图控制器,你可以将它连接到FlipTestViewController中的控件(通常是一个按钮):

- (IBAction)dismissViewController:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

这解除了具有相同翻转动画的视图控制器

答案 1 :(得分:1)

听起来最简单的方法就是重置应用程序窗口的rootViewController属性。从应用程序的任何位置,您都可以使用[UIApplication sharedApplication] .delegate.window.rootViewController获取对根视图控制器的引用。因此,在您用于切换到下一个视图控制器的任何操作方法中,您可以为控制器分配init,然后将窗口的rootViewController属性设置为该控制器。如果您没有保留对控制器的其他引用,则在重置属性时可能会取消分配旧的(可能是您想要的也可能不是 - 您可能希望有一些属性可以跟踪高分或在哪里例如,玩家在游戏中。)

在app委托中,通常有类似这样的代码(当你从单个视图项目开始时):

 WelcomeController *welcome = [[WelcomeController alloc] initWithNibName:@"ViewController" bundle:nil];
 self.window.rootViewController = welcome;

因此,我会在您的app委托中添加类似的内容,以及您想要在启动时显示的任何视图控制器。然后在你的视图控制器代码中(或者你把按钮切换到视图控制器的任何地方)你会有类似的东西(我在我的测试项目中使用了分段控件):

-(IBAction)selectController:(UISegmentedControl *)sender {
    if (sender.selectedSegmentIndex == 0) {
        PlayViewController *player = [[PlayViewController alloc] initWithNibName:@"PlayViewController" bundle:nil];
        [UIApplication sharedApplication].delegate.window.rootViewController = player;
    }else{
        HighScores *scorer = [[HighScores alloc] initWithNibName:@"HighScores" bundle:nil];
        [UIApplication sharedApplication].delegate.window.rootViewController = scorer;
    }
}

答案 2 :(得分:0)

一种简单的方法是使用导航控制器。您可以获得推/弹的好处,这有助于屏幕序列。

然后您可以使用以下命令弹出特定控制器:

- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated

这使您可以转到已经显示的特定视图控制器,而无需浏览所有其他视图控制器。

另外,知之甚少,您可以用

替换整个控制器堆栈
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated

也将索引零处的控制器替换为基本控制器。

因此,您可以轻松获得顶部工具栏和所有导航控制器功能,当您只想将所有内容重置为某个控制器时,您就可以...

    [navController setViewControllers:@[viewController] animated:YES];

修改

听起来你并不确定自己想要什么。因此,你应该给自己一些余地,而不是试图重新发明轮子。

我认为导航控制器是最佳选择。它已经知道如何管理多个控制器,并且使用setViewControllers可以使它看起来像是从任何控制器到任何其他控制器,但是你可以保持与主要工作中心相同的导航控制器。 / p>

否则,您仍然可以使用

自己完成所有这些操作
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion

- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion

您可以从根视图控制器中调用它们。当您想要更改控制器时,它将只关闭当前控制器并显示新控制器。