【问题标题】:How To Navigate Objective-C App Programmatically Without Using Only Storyboard?如何在不使用情节提要的情况下以编程方式导航 Objective-C 应用程序?
【发布时间】:2019-11-03 11:50:32
【问题描述】:

我在浏览我的应用程序时遇到问题。我用Objective-C完全用Sprite Kit(所有按钮等使用SKNodes)编写了一个游戏场景。当用户打开应用程序时,它会显示一个完全内置于 Storyboard 中的主菜单,其中包含一个 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];
}

这也允许我通过更改标识符导航到主菜单。除了一个问题之外,它就像一个魅力:它永远不会从堆栈中弹出旧的 ViewControllers。因此,在运行应用程序时,每次我导航到下一个 ViewController 时,它都会为处理内存增加约 40MB。这意味着每次用户输掉重新开始游戏,都会占用越来越多的内存。我试图改用它:

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

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

[self.navigationController popViewControllerAnimated:YES];

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

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

感谢大家的帮助。

【问题讨论】:

  • 从脑海中浮现出使用视图控制器重新启动场景的想法,您第一次就做对了。
  • 在我开始帮助你之前,请先回答这个问题:你希望不同设备上的玩家有相同的体验吗?例如。你正在做一场乒乓球比赛,你希望你的球在 1 秒内在所有设备上从上到下。请注意,这不包括从左到右,因为这是不同纵横比的问题。
  • 游戏玩法只取决于场景的宽度。因此,(正如您在此处回答的那样:stackoverflow.com/questions/34499143/…)设置游戏所基于的恒定宽度在设备之间保持一致正是我所需要的。高度的不同并不重要。这基本上是这里推荐的:“developer.apple.com/documentation/spritekit/skscene/…
  • 除非有一些背景问题是由更改视图控制器而不是更改场景引起的,否则更改视图控制器似乎是一种更简洁的方式来导航应用程序,而不必过多地与生命周期搏斗的场景。记忆力似乎也轻了很多。
  • 如果你只需要一个恒定的宽度,不要使用视图大小。我将不得不为这个问题写一个新的答案,因为那个答案是 iphone X 之前的。你现在需要做的方法是使用适合 iphone X 比例的静态大小创建你的场景,然后使用你的视图来填充你的短条上的场景

标签: ios objective-c xcode uiviewcontroller storyboard


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    相关资源
    最近更新 更多