从 UIViewController 打开 SKScene 时出现 NSInvalidArgumentException

Posted

技术标签:

【中文标题】从 UIViewController 打开 SKScene 时出现 NSInvalidArgumentException【英文标题】:NSInvalidArgumentException when opening SKScene from UIViewController 【发布时间】:2015-03-27 06:11:24 【问题描述】:

我正在创建我的第一个 SpriteKit 游戏,这就是我想要做的:

1.删除默认 Main_iphone 和 Main_ipad 故事板

info.plist 中删除Main_iphoneMain_ipad 列表。 从Main Interface下删除Main_iPhone.storyboard deployment info

2。在didFinishLaunchingWithOptions下的AppDelegate.m中添加如下代码

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[CMViewController alloc] init];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];

    return YES;

3.在 viewController.m 中配置 SKScene

-(void)viewWillLayoutSubviews
    [super viewWillLayoutSubviews];
    //Configure the view.
    SKView* skView = (SKView*)self.view;
    //Create and configure the scene.
    SKScene* scene = [CMHomeScene sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;
    //Present the scene.
    [skView presentScene:scene];
 

运行时错误

-[UIView presentScene:]:无法识别的选择器发送到实例 0x155854d0 *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[UIView presentScene:]:无法识别的选择器发送到实例 0x155854d0” **** 首先抛出调用堆栈: (0x2c3eac1f 0x39b95c8b 0x2c3f0039 0x2c3edf57 0x2c31fdf8 0x10883d 0x2f8a7433 0x2f2cfa0d 0x2f2cb3e5 0x2f2cb26d 0x2f2cac51 0x2f2caa55 0x2fb0b1c5 0x2fb0bf6d 0x2fb16379 0x2fb0a387 0x32b770e9 0x2c3b139d 0x2c3b0661 0x2c3af19b 0x2c2fd211 0x2c2fd023 0x2f90e3ef 0x2f9091d1 0x10c2d1 0x3a115aaf) libc++abi.dylib:以 NSException 类型的未捕获异常终止 (lldb)

PS:

当我不删除情节提要和修改 info.plist 时,我的所有场景都可以正常工作。 我正在以编程方式创建所有场景和视图控制器。 我尝试过初始化 self.view = [[SKView alloc]initWithFrame:self.view.frame]-(void)loadView

【问题讨论】:

【参考方案1】:

您已分配SKView* skView = (SKView*)self.view。 我相信 self.view 不是 SKView 的子类,所以简单地进行类型转换会将您的 SKView 指向 UIView。

虽然构建代码会成功,但您肯定会遇到运行时错误,因为您的 SKView 会发现 self.view 将其真实身份 (UIView) 隐藏在 nil 指针 SKView 后面。

您可能想要更改您的3。配置视图如下:

    - (void)viewWillLayoutSubviews 
     
    // Configure the view. 
    SKView* skView = [[SKView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    // Create and configure the scene. 
    SKScene* scene = [CMHomeScene sceneWithSize:skView.bounds.size]; 
    scene.scaleMode = SKSceneScaleModeAspectFill; 
    // Present the scene. 
    [skView presentScene:scene]; 
[self.view addSubview:skView];
    

【讨论】:

【参考方案2】:

引发异常是因为您试图在 UIView 类型的视图上调用 presentScene,而方法属于 SKView

Storyboard 默认将self.view 类设置为SKView。由于您已删除情节提要,并尝试使用通常初始化的控制器,self.view 将被启动为 UIView 而不是 SKView

希望对你有帮助。

【讨论】:

我明白你的意思,但我理解接受的答案写得不好,这就是它被编辑的原因。另外,我没有使用任何 XIB,所以我必须创建一个 SKView 并将其作为子视图添加到我的视图控制器,而不是完全子类化我的视图控制器。希望这会有所帮助。 是的,这就是你必须做的@madLokesh :) 这就是我所做的。请参阅更新的答案。感谢您的努力,我真的很感激。一个upvote表示我的赞赏。希望我的问题也能得到赞赏并帮助其他访问它的人。 感谢@madLokesh 的赞赏... :)

以上是关于从 UIViewController 打开 SKScene 时出现 NSInvalidArgumentException的主要内容,如果未能解决你的问题,请参考以下文章

xCode 8.x 因“GameScene.sks”文件而崩溃

如何从sks文件加载节点,然后应用在Scene Editor中定义的操作

从 UIViewController 打开 SKScene 时出现 NSInvalidArgumentException

如何以编程方式使用另一个视图中的按钮从情节提要中打开 UIViewController?

SpriteKit .sks文件在分配纹理时崩溃Xcode 10

Swift IOS:从通知打开应用程序时调用 UIviewController 的特定功能