Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Halt when presenting ViewController with SKScene

EDIT: OK, so this happens even with an empty SpriteKit scene! What could be wrong here?? Why does iOS need 2 seconds to display SpriteKit scene??

EDIT 2: First time i click on tab bar to display view controller with SKScene it displays immediately, but every next time i try to navigate back to this view controller it will take it 2 seconds to display!

I have a a tab bar controller in my app with multiple different viewControllers.

One of them contains a SpriteKit scene, with a couple of nodes, 5 of them, nothing too heavy.

In simulator everything is fine, but when testing on the device i noticed that sometime there is a big halt ( around 2 seconds! ) when changing to ViewController with the SpriteKit scene.

Other times there is no halt and view is displayed immediately.

Now, i know there must be something I'm doing wrong here, because iOS should definitely be able to handle this.

This is my viewDidLoad function inside the viewController with the spriteKit scene:

override func viewDidLoad() {
    super.viewDidLoad()

    if let scene = MyScene(fileNamed:"MyScene") {
        // Configure the view.
        scene.switchView = switchView

        let parentNode = scene.childNodeWithName("WholeObject") as! SKSpriteNode
        let contentNode = scene.childNodeWithName("CenterNode") as! SKSpriteNode
        addPhotoToFrame(contentNode, photoName: "woman", maskName: "circleMask")

        let node1 = parentNode.childNodeWithName("node1")  as! SKSpriteNode
        addPhotoToFrame(zealNode1, photoName: "motherCircleImage", maskName: "circleMaskSmall")

        let node2 = parentNode.childNodeWithName("node2")  as! SKSpriteNode
        addPhotoToFrame(zealNode2, photoName: "hairstylistCircleImage", maskName: "circleMaskSmall")

        let node3 = parentNode.childNodeWithName("node3")  as! SKSpriteNode
        addPhotoToFrame(zealNode3, photoName: "dietCircleImage", maskName: "circleMaskSmall")


        let skView = self.view as! SKView
        skView.showsFPS = true
        skView.showsNodeCount = true


        /* Sprite Kit applies additional optimizations to improve rendering performance */
        skView.ignoresSiblingOrder = true

        /* Set the scale mode to scale to fit the window */
        scene.scaleMode = .AspectFill


        skView.presentScene(scene)
    }

}
like image 697
deloki Avatar asked Oct 21 '15 18:10

deloki


2 Answers

I have no idea what triggers the issue but pausing before the view disappeared fixed it for me.

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.contentView.paused = false
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    self.contentView.paused = true
}
like image 97
Tom Avatar answered Sep 30 '22 05:09

Tom


hi deloki i created a new project in swift and come with a solution its working fine on device..... check out my code

here is my GameViewController which call GameScene

import UIKit
import SpriteKit

extension SKNode {
    class func unarchiveFromFile1(file : String) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! GameScene
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

class GameViewController: UIViewController {
       var skView:SKView!
    override func viewDidLoad() {

        super.viewDidLoad()

        if let scene = GameScene.unarchiveFromFile1("GameScene") as? GameScene {
            // Configure the view.
            let graphRect:CGRect = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
             skView = SKView();
             skView.frame=graphRect
            skView.showsFPS = true
            skView.showsNodeCount = true
            self.view.addSubview(skView)
            /* Sprite Kit applies additional optimizations to improve rendering performance */
            skView.ignoresSiblingOrder = true

            /* Set the scale mode to scale to fit the window */
            scene.scaleMode = .AspectFill

            skView.presentScene(scene)
            let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(3 * Double(NSEC_PER_SEC)))
            dispatch_after(delayTime, dispatch_get_main_queue()) {
                let s2=GameViewController1();
                self.presentViewController(s2, animated: true, completion: { () -> Void in
                    //
                })
            }

        }
    }
    override func viewDidDisappear(animated: Bool) {
        if((skView) != nil)
        {
            skView .removeFromSuperview();
            skView=nil;
        }

    }
    override func shouldAutorotate() -> Bool {
        return true
    }

    override func supportedInterfaceOrientations() -> Int {
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
            return Int(UIInterfaceOrientationMask.AllButUpsideDown.rawValue)
        } else {
            return Int(UIInterfaceOrientationMask.All.rawValue)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }
}

here is my GameViewController1 which call MyScene1

import UIKit
import SpriteKit

extension SKNode {
    class func unarchiveFromFile(file : String) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! GameScene
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

class GameViewController1: UIViewController {
      var skView:SKView!
    override func viewDidLoad() {

        super.viewDidLoad()

        if let scene = GameScene.unarchiveFromFile("MyScene1") as? GameScene {
            // Configure the view.
            let graphRect:CGRect = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
            skView=SKView()
            skView.frame=graphRect
            skView.showsFPS = true
            skView.showsNodeCount = true

            /* Sprite Kit applies additional optimizations to improve rendering performance */
            skView.ignoresSiblingOrder = true

            /* Set the scale mode to scale to fit the window */
           // scene.scaleMode = .AspectFill
            self.view.addSubview(skView)
            skView.presentScene(scene)
            let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(3 * Double(NSEC_PER_SEC)))
            dispatch_after(delayTime, dispatch_get_main_queue()) {
                let s2=GameViewController();
                self.presentViewController(s2, animated: true, completion: { () -> Void in
                    //
                })
            }
        }
    }

    override func viewDidDisappear(animated: Bool) {
        if((skView) != nil)
        {
            skView .removeFromSuperview();
            skView=nil;
        }

    }
    override func shouldAutorotate() -> Bool {
        return true
    }

    override func supportedInterfaceOrientations() -> Int {
        if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
            return Int(UIInterfaceOrientationMask.AllButUpsideDown.rawValue)
        } else {
            return Int(UIInterfaceOrientationMask.All.rawValue)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }
}

creating SKview from storyboard i just created it from programmitically and every 2 second i am switching from one view to another and its working fine on all device but one thing i used Xcode 6.4 and ios9 you can download link from http://www.filedropper.com/tryit

like image 39
dragoneye Avatar answered Sep 30 '22 06:09

dragoneye