Как перейти от SKScene к UIViewController по коду?

все, что я хочу, если, когда пользователь касается skspritenode в skscene, он перейдет к другому представлению, например performseguewithidentifier. Спасибо за любую помощь. Я могу отправить код, но это похоже на общий вопрос, поэтому я решил, что вам не понадобится. Кстати, я уже выяснил, как обнаружить нажатие на skspritenode. Я смотрю на это уже давно, и я в тупике. Пожалуйста помочь.

3 ответов


вы не можете представить viewController из SKScene, поскольку он фактически отображается только в SKView. Вам нужен способ отправить сообщение в viewController SKView, который, в свою очередь, представит viewController. Для этого можно использовать делегирование или NSNotificationCenter.

делегация

добавьте следующее определение протокола в SKScene .H-файл:

@protocol sceneDelegate <NSObject>
-(void)showDifferentView;
@end

и объявить свойство делегата в интерфейс:

@property (weak, nonatomic) id <sceneDelegate> delegate;

затем, в точке, где вы хотите представить экран share, используйте эту строку:

[self.delegate showDifferentView];

теперь, в вашем viewController .H-файл, осуществлению протокола:

@interface ViewController : UIViewController <sceneDelegate>

и, в Вашему .M файл, добавьте следующую строку перед представлением сцены:

scene.delegate = self;

затем добавьте туда следующий метод:

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

NSNotificationCenter

сохранить метод-showDifferentView как описано в предыдущей альтернативе.

добавьте viewController в качестве прослушивателя к уведомлению в методе-viewDidLoad:

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

затем, в сцене в точке, где вы хотите показать этот viewController, используйте эту строку:

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

Я предлагаю следующий вариант: (это идет в вашу сцену)

-(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];
}

и позже в вашем контроллере просмотра, когда вы хотите его отклонить, сделайте что-то вроде этого:

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

хорошая вещь об этой опции заключается в том, что вам не нужно будет хранить ваше представление, так как в любой момент Вы можете инициализировать его, пока сцена, в которой вы находитесь, импортирует код viewcontroller.

Дайте мне знать, если это работает


ZeMoon, хороший ответ, но что, если несколько сцен хотят показать один и тот же контроллер вида, например, экран настроек? Вы не хотите определять несколько протоколов делегирования сцены, которые делают то же самое.

другая идея-определить один протокол, который обрабатывает представление различных контроллеров представления для вас:

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

параметр сцены может использоваться для принятия решений на основе того, откуда вы пришли.

контроллер представления вашей игры (или любого другого объекта) реализует протокол. Все сцены, отображающие другой экран, получают слабую ссылку на контроллер:

@property (nonatomic, weak) id<ScreenFlowController> screenFlowController;