How to Present a Uiviewcontroller from Skscene

Getting the UIViewController from an SKScene

Your view controller is:

self.view?.window?.rootViewController

Example:

        let isReady = GADRewardBasedVideoAd.sharedInstance().isReady          
guard let controller = self.view?.window?.rootViewController as? GameViewController else {return}

if isReady {
print("ADMOB: started")
GADRewardBasedVideoAd.sharedInstance().present(fromRootViewController: controller)
}

How To Present a SKScene from a UIViewController

I think I might have found a solution-I didn't present the GameScene directly from the MenuViewController, but instead, when the playButton is pressed I transitioned to the GameViewController and then presented the GameScene from there.

I don't know why it doesn't work in the MenuViewController, but this method works.

Presenting a UIViewController from SKScene shows black screen

To present a SKScene from another SKScene you should do for example :

let nextScene = MainScene(size: self.scene!.size)
self.scene?.view?.presentScene(nextScene, transition: SKTransition.doorway(withDuration: 1))

You don't need to retrieve your currentViewController because you have always access to the view of your scene


As explained to the comments below, there are various methods to call a function implemented to your game viewController, one could be to create a delegate/protocol as showed in this code:

GameScene example:

import SpriteKit
protocol GameViewControllerDelegate: class {
func callMethod(inputProperty:String)
}
class GameScene: SKScene {
weak var gameViewControllerDelegate:GameViewControllerDelegate?
override func didMove(to view: SKView) {
gameViewControllerDelegate?.callMethod(inputProperty: "call game view controller method")
}
}

GameViewController example:

class GameViewController: UIViewController, GameViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") {
let gameScene = scene as! GameScene
gameScene.gameViewControllerDelegate = self
gameScene.scaleMode = .aspectFill
view.presentScene(gameScene)
}
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
func callMethod(inputProperty:String) {
print("inputProperty is: ",inputProperty)
}
}

Output:

Sample Image

How do I present a UIViewController from SKScene?

You're creating a new view controller but never presenting it:

SpriteViewController *viewController = [SpriteViewController alloc];

I'm assuming that SpriteViewController is what presents your SpriteMyScene, and you'd like to hand control back to the presenting SpriteViewController.

You need to keep a reference to SpriteViewController in your SpriteMyScene subclass, and then access that reference when you call openTweetSheet.

in SpriteMyScene.h

@class SpriteViewController;

@interface SpriteMyScene : SKScene

@property (nonatomic, weak) SpriteViewController *spriteViewController;

@end

in SpriteViewController.m

// somewhere you initialize your SpriteMyScene object, I'm going to call it myScene

myScene.spriteViewController = self;

in SpriteMyScene.m

#import "SpriteViewController.h"

- (void)sendToController
{
NSLog(@"ok");
// use the already-created spriteViewController
[_spriteViewController openTweetSheet];
}

Moving from SKScene to ViewController

Replace the code related to currentViewController with this:

self.view?.window?.rootViewController?.present(viewController, animated: true, completion: nil)

It should work.
You can also create a segue in Storyboard and call it like this:

self.view?.window?.rootViewController?.performSegue(withIdentifier: "VC", sender: self)

EDIT:

I've tried on one of my app now the next solution and it worked:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "VC")
vc.view.frame = rootViewController.view.frame
vc.view.layoutIfNeeded()

UIView.transition(with: window, duration: 0.3, options: .transitionFlipFromRight, animations:
{
window.rootViewController = vc
}, completion: { completed in
// maybe do something here
})

To me it worked, I hope it will solve your case :)

Presenting a viewController on SKScene

We can use "presentModalViewController" by using this code to access the root view controller

 UIViewController *vc = self.view.window.rootViewController;
[vc presentViewController: activityViewController animated: YES completion:nil];

now it works fine !



Related Topics



Leave a reply



Submit