使用SKScene呈现ViewController时暂停

时间:2023-01-22 23:08:32

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??

编辑:好的,所以即使有一个空的SpriteKit场景也会发生这种情况!这可能有什么不对?为什么iOS需要2秒才能显示SpriteKit场景?

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!

编辑2:我第一次点击标签栏以显示带有SKScene的视图控制器,它立即显示,但每次下次我尝试导航回此视图控制器时,它将花费2秒钟显示!

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

我的应用程序中有一个带有多个不同viewControllers的标签栏控制器。

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

其中一个包含一个SpriteKit场景,有几个节点,其中5个节点,没有太重。

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.

在模拟器中一切都很好,但是当在设备上进行测试时,我注意到当使用SpriteKit场景更改为ViewController时,有时会出现大停顿(大约2秒!)。

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.

现在,我知道必须有一些我在这里做错了,因为iOS绝对应该能够解决这个问题。

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

这是viewController里面的viewDidLoad函数和spriteKit场景:

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)
    }

}

2 个解决方案

#1


1  

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

嗨deloki我在swift中创建了一个新项目并提供了一个解决方案,它在设备上工作正常.....检查我的代码

here is my GameViewController which call GameScene

这是我的GameViewController,它调用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

这是我的GameViewController1,它调用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

从故事板创建SKview我只是从程序上创建它,每2秒钟我从一个视图切换到另一个视图并且它在所有设备上工作正常但有一件事我使用Xcode 6.4和ios9你可以从http://www.filedropper下载链接.COM / tryit

#2


1  

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
}

#1


1  

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

嗨deloki我在swift中创建了一个新项目并提供了一个解决方案,它在设备上工作正常.....检查我的代码

here is my GameViewController which call GameScene

这是我的GameViewController,它调用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

这是我的GameViewController1,它调用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

从故事板创建SKview我只是从程序上创建它,每2秒钟我从一个视图切换到另一个视图并且它在所有设备上工作正常但有一件事我使用Xcode 6.4和ios9你可以从http://www.filedropper下载链接.COM / tryit

#2


1  

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
}