¿Cómo paso de SKScene a UIViewController por código?

Todo lo que quiero es que cuando el usuario toque un skspritenode en el skscene, vaya a una vista diferente como performseguewithidentifier . Gracias por cualquier ayuda. Puedo publicar el código, pero parece ser una pregunta genérica, así que pensé que no necesitarías ninguno. Por cierto, ya descubrí cómo detectar el tapping en skspritenode. He estado mirando esto por un largo tiempo y estoy perplejo. Por favor ayuda.

No puede presentar un viewController dentro de un SKScene, ya que en realidad solo se representa en un SKView. Necesita una forma de enviar un mensaje al viewController de SKView, que a su vez presentará viewController. Para esto, puede usar la delegación o NSNotificationCenter.

Delegación

Agregue la siguiente definición de protocolo al archivo .h de su SKScene:

 @protocol sceneDelegate  -(void)showDifferentView; @end 

Y declare una propiedad de delegado en la interfaz:

 @property (weak, nonatomic) id  delegate; 

Luego, en el punto donde desea presentar la pantalla de compartir, use esta línea:

 [self.delegate showDifferentView]; 

Ahora, en el archivo .h de viewController, implemente el protocolo:

 @interface ViewController : UIViewController  

Y, en su archivo .m, agregue la siguiente línea antes de presentar la escena:

 scene.delegate = self; 

A continuación, agregue el siguiente método allí:

 -(void)showDifferentView { [self performSegueWithIdentifier:@"whateverIdentifier"]; } 

NSNotificationCenter

Guarde el método -showDifferentView como se describe en la alternativa anterior.

Agregue viewController como un oyente a la notificación en su método -viewDidLoad:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showDifferentView) name:@"showDifferenView" object:nil]; 

Luego, en la escena en el punto donde quieres mostrar este viewController, usa esta línea:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"showDifferentView" object:nil]; 

Sugiero la siguiente opción: (esto va en tu escena)

 -(void)presentViewController{ MyViewController *myController = [[MyViewController alloc]init]; //Or instantiate any controller from the storyboard with an indentifier [self.view.window.rootViewController presentViewController:myController animated: YES options: nil]; } 

Y más tarde en su controlador de vista, cuando desee descartarlo, haga algo como esto:

 -(void)dismissItself:(id)sender { [self dismissViewControllerAnimated:YES completion:nil]; } 

Lo bueno de esta opción es que no necesitará almacenar su vista ya que en cualquier punto puede inicializarla mientras que la escena en la que se encuentre, importe el código del controlador de visualización.

Déjame saber si funciona

ZeMoon, buena respuesta, pero ¿y si varias escenas quieren mostrar el mismo controlador de vista, por ejemplo, alguna pantalla de configuración? No desea definir múltiples protocolos delegates de escena que hagan lo mismo.

Otra idea es definir un protocolo único que maneje la presentación de diferentes controladores de vista por usted:

 @protocol ScreenFlowController  - (void)presentSettingsScreenFromScene:(SKScene *)scene; - (void)presentCreditsScreenFromScene:(SKScene *)scene; @end 

El parámetro de escena se puede usar para tomar decisiones en función de su procedencia.

El controlador de vista de su juego (o cualquier otro objeto) implementa el protocolo. Todas las escenas que muestran una pantalla diferente reciben una referencia débil al controlador:

 @property (nonatomic, weak) id screenFlowController;