如何在不仅使用情节提要的情况下以编程方式导航Objective-C应用程序?

时间:2019-06-20 15:49:44

标签: ios objective-c xcode uiviewcontroller storyboard

我在浏览应用程序时遇到麻烦。我已经用Objective-C完全在Sprite Kit中编写了一个游戏场景(使用SKNode的所有按钮等)。当用户打开应用程序时,它会显示一个主菜单,该菜单完全内置在Storyboard中,并且包含一个UIButton,该UIButton触发了到其中包含我的游戏场景的ViewController的过渡。

最初,一旦用户迷路,我要重新启动游戏,我只是提出了一个新的场景:

GameScene *newScene = [GameScene sceneWithSize:self.view.bounds.size];
newScene.anchorPoint = CGPointMake(0.5, 0.5);
[self.view presentScene:newScene transition:[SKTransition fadeWithDuration:1]];
[self removeAllChildren];
[newScene sceneSetupWithSize:screenSize];

sceneSetupWithSize:(CGSize)size是我用来设置游戏的自定义方法。不幸的是,无论我发送什么值,这个新场景始终具有相同的不正确大小。此过程也使我无法导航回主菜单。

要解决此问题,我决定只调用场景的ViewController。我是通过在游戏场景类中创建一个ViewController对象来做到这一点的:

@property (nonatomic) GameViewController *currentController;

然后在ViewController加载场景时分配控制器:

sceneNode.currentController = self;

然后我使用该对象从游戏场景类中调用ViewController中的自定义方法,如下所示:

// In Game Scene Class
[self removeAllChildren];
[self removeAllActions];
[_currentController restart];

// In ViewController Class
- (void)restart{
     NSLog(@"Restarting Scene");

     NSString * storyboardName = @"Main";
     UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
     UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"GameView"];
     vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
     [self presentViewController:vc animated:YES completion:nil];
}

这也使我只需更改标识符即可导航到主菜单。除了一个问题外,它的工作原理很吸引人:它永远不会从堆栈中弹出旧的ViewController。因此,在运行该应用程序时,每次导航到下一个ViewController时,它都会在处理内存中添加约40MB。这意味着每当用户丢失并重新启动游戏时,它将占用越来越多的内存。我试图用它代替:

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

但是它只是给我一个空白屏幕。我什至尝试像这样随后弹出当前控制器:

[self.navigationController popViewControllerAnimated:YES];

但是没有任何效果。我假设self.navigationControllernil,但是我不知道该怎么做。我不希望在游戏场景中使用任何UIButton。我也希望按原样使用游戏场景,而无需在Storyboard中重新创建它。

我知道那里也有类似的问题,我已经阅读了大多数问题,但没有一个对我有帮助。

谢谢大家的帮助。

1 个答案:

答案 0 :(得分:0)

这使我花了很长时间才意识到。我一直试图做的只是更改根视图。这段代码解决了我的问题:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"GameView"];
vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
UIApplication.sharedApplication.delegate.window.rootViewController = vc;