从CCLayer做故事板

时间:2013-08-19 10:39:00

标签: ios objective-c cocos2d-iphone storyboard

我有一个项目,我使用故事板,导航控制器,故事板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的子类的子类中。

5 个答案:

答案 0 :(得分:1)

好的,我想我得到了这个。我尝试了很多方法,主要问题是GameLayer是CCLayer,很难找到包含它的ViewController。

您需要引用cocos2dViewController ViewController来执行segue,我的解决方案并不理想,但在这种情况下它可以正常工作。

我使用NSNotificationCenter从GameLayer发布通知,然后添加cocos2dViewController控制器作为观察者。当cocos2dViewController控制器收到通知时,您执行segue

[self performSegueWithIdentifier:@"segueFromCocos" sender:self];

这些是确切的步骤:

  1. 将新的视图控制器拖到故事板
  2. 从cocos2dViewController创建一个push segue到新创建的ViewController,并将此segue标识符:“segueFromCocos”添加到segue
  3. 将segal到cocos2dViewController的segue从modal更改为push
  4. 在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

    中推送通知
    • (无效)nextButtonClicked:(ID)发送方 { NSLog(@“发布通知”); [[NSNotificationCenter defaultCenter] postNotificationName:@“TestNotification”对象:self]; }
  5. 然后在cocos2dViewController视图控制器的viewDidLoad方法中注册cocos2dViewController作为观察者:

    [[NSNotificationCenter defaultCenter] addObserver:self                                                  选择:@选择(receiveTestNotification :)                                                      名:@ “TestNotification”                                                    对象:无];

  6. 最后在receiveTestNotification中:执行segue:

    • (void)receiveTestNotification:(NSNotification *)通知 { if([[notification name] isEqualToString:@“TestNotification”]){     NSLog(@“已成功收到测试通知!%@”,[自我类]);

      [self performSegueWithIdentifier:@"segueFromCocos" sender:self];
      

      } }

  7. 抱歉代码格式化问题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。相反,您应该将您的游戏结合屏幕显示为全新CCSceneCCLayer,只需将其添加为您的父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吗?