我有一个项目,我使用故事板,导航控制器,故事板segues。我在其中一个视图中有一个cocos2d视图。视图GameLayer
具有类CCLayer
,它嵌入在cocos2dViewController cocos2dViewController : CCViewController
中,而CCViewController又是CCViewController : UIViewController
的子类。所以,在我的Cocos2d视图中,它是一个CCLayer,不能使用[self performSegue ....]方法,因为它不是uiviewcontroller的直接子类或其他东西。
我试过
GameOverViewController *gameOver = [[GameOverViewController alloc]init];
UIViewController* rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
[rootViewController presentViewController:gameOver animated:YES completion:NULL];
但那只是让我Warning: Attempt to present <GameOverViewController: 0x107d0060> on <UINavigationController: 0x9d33890> whose view is not in the window hierarchy!
我也试过
GameOverViewController *gameOver = [[GameOverViewController alloc]init];
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] presentModalViewController:gameOver animated:YES];
但这根本没有做任何事情
所以我需要在其中一个更高级的类上执行一个选择器,它是UIViewController的子类,在这种情况下,我该怎么做?
或者我需要从CCLayer执行segue,在这种情况下我该怎么做?对我来说没关系:)
编辑:澄清问题:
我需要从我的GameLayer做一个segue,这是一个CCLayer
子类,因此它不能使用普通的segue方法。 GameLayer嵌入了cocos2dViewController
中的CCViewController
,它是{{1}}的子类,最终是UIViewController的子类。我在我的项目中使用故事板,而CCViewController是响应IBOutlets的视图控制器。所以我需要从我的游戏层以某种方式从这个文件推送segue。你可以在这里看到游戏系统:mediafire.com/?7dil7uolo5k1syr来自我制作的模板。我想从游戏视图控制器中拉出一个segue到另一个视图。到目前为止,我已尝试过在另一个文件,ccdirector等中执行此操作的各种方法。
对于那些不熟悉cocos2d的人来说,CCLayer是CCNode的子类,它是NSObject的子类。所以你可以看到这是一个关于如何从NSObject在UIViewController中执行segue的问题。
所以tl; dr:来自CCLayer(NSObject)的故事板segue嵌入在UIViewController的子类的子类中。
答案 0 :(得分:1)
好的,我想我得到了这个。我尝试了很多方法,主要问题是GameLayer是CCLayer,很难找到包含它的ViewController。
您需要引用cocos2dViewController ViewController来执行segue,我的解决方案并不理想,但在这种情况下它可以正常工作。
我使用NSNotificationCenter从GameLayer发布通知,然后添加cocos2dViewController控制器作为观察者。当cocos2dViewController控制器收到通知时,您执行segue
[self performSegueWithIdentifier:@"segueFromCocos" sender:self];
这些是确切的步骤:
在init方法中向GameLayer添加一个按钮:
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[nextButton setTitle:@"next" forState:UIControlStateNormal];
nextButton.tag = 123;
nextButton.frame = CGRectMake(10.0, 10.0, 90.0, 40.0);
[nextButton addTarget:self
action:@selector(nextButtonClicked:)
forControlEvents:UIControlEventTouchDown];
UIView *glView = [CCDirector sharedDirector].view;
[glView addSubview:nextButton];
此按钮将在nextButtonClicked:selector
中推送通知然后在cocos2dViewController视图控制器的viewDidLoad方法中注册cocos2dViewController作为观察者:
[[NSNotificationCenter defaultCenter] addObserver:self 选择:@选择(receiveTestNotification :) 名:@ “TestNotification” 对象:无];
最后在receiveTestNotification中:执行segue:
(void)receiveTestNotification:(NSNotification *)通知 { if([[notification name] isEqualToString:@“TestNotification”]){ NSLog(@“已成功收到测试通知!%@”,[自我类]);
[self performSegueWithIdentifier:@"segueFromCocos" sender:self];
} }
抱歉代码格式化问题btw:)
我更改了代码并使其在没有通知的情况下工作。问题是获取对cocos2dViewController ViewController的引用,以便您可以从那里执行segue。
您首先需要获取对rootViewController的引用,这是一个UINavigationController,然后您只需从导航/根视图控制器获取最后一个控制器:
[navC.viewControllers lastObject];
这是您触摸下一个按钮时运行的代码:
UIViewController *root = [[[UIApplication sharedApplication] delegate] window].rootViewController;
if ( [root isKindOfClass:[UINavigationController class]] ) {
UINavigationController *navC = (UINavigationController *)root;
cocos2dViewController *cocosVC = (cocos2dViewController *)[navC.viewControllers lastObject];
[cocosVC performSelector:@selector(asdf)];
}
然后在cocos2dViewController中你有asdf选择器,它只是执行segue:
- (void)asdf
{
[self performSegueWithIdentifier:@"segueFromCocos" sender:self];
}
答案 1 :(得分:1)
如果您不想在此处使用通知,请执行以下操作:
我更改了代码并使其在没有通知的情况下工作。问题是获取对cocos2dViewController ViewController的引用,以便您可以从那里执行segue。
您首先需要获取对rootViewController的引用,这是一个UINavigationController,然后您只需从导航/根视图控制器获取最后一个控制器:
[navC.viewControllers lastObject];
这是您触摸下一个按钮时运行的代码:
UIViewController *root = [[[UIApplication sharedApplication] delegate] window].rootViewController;
if ( [root isKindOfClass:[UINavigationController class]] ) {
UINavigationController *navC = (UINavigationController *)root;
cocos2dViewController *cocosVC = (cocos2dViewController *)[navC.viewControllers lastObject];
[cocosVC performSelector:@selector(asdf)];
}
然后在cocos2dViewController中你有asdf选择器,它只是执行segue:
- (void)asdf
{
[self performSegueWithIdentifier:@"segueFromCocos" sender:self];
}
答案 2 :(得分:0)
我不建议在使用segues
时弄乱Cocos2d
。相反,您应该将您的游戏结合屏幕显示为全新CCScene
或CCLayer
,只需将其添加为您的父CCNode
的子项。如果您的gameover屏幕是某种弹出/对话框,您也可以尝试使用透明的黑色背景颜色CCLayerColor
。
答案 3 :(得分:0)
GameOverViewController *gameOver = [self.storyboard instantiateViewControllerWithIdentifier:@"GameOverViewController"];
UINavigationController *navController=[[UINavigationController new]initWithRootViewController:gameOver];
[self.navigationController presentViewController:navController animated:YES completion:Nil];
你应该尝试下面显示相同错误的链接 - 警告:尝试呈现:0xab5d9d0,其视图不在窗口层次结构中! Whose view is not in window hierarchy issue
答案 4 :(得分:0)
我完全同意ssantos及其解决方案,但如果你坚持尝试将UIKit和cocos2D混合在一起:
尝试[self performSegue....]
而不是“[[CCDirector sharedDirector] performSegue....]
方法”,因为导演是UIViewController的子类。
我不能确定这是否有效,因为你以非常规的方式使用cocos2D。
另一个观察结果:
您说GameLayer
嵌入了cocos2dViewController
..是否有对该视图控制器的引用?你可以打电话给performSegue
吗?