SpriteKit: Activity Indicator now showing with a specific scene

Hello. I have faced a strange dilemma that I have been trying to solve for many days now.


I have a UIViewController where I implement the following method:


override func viewWillAppear(animated: Bool)
    {
        self.activityIndicator.startAnimating()
        self.btnMetar.enabled = false
        self.btnWindAloft.enabled = false
   
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(dispatch_get_global_queue(priority, 0))
            {
                self.spriteViewDep = nil
                self.spriteViewDest = nil
                self.spriteViewAlt = nil
           
                if self.spriteViewDep == nil
                {
                    let sceneDepWidth = self.viewDep.bounds.size.width
                    let sceneDepHeight = self.viewDep.bounds.size.height
                    let sceneDepSize = CGSizeMake(sceneDepWidth, sceneDepHeight)
                    let sceneDep = IGAAirportDepartureScene(size: sceneDepSize)
                    self.spriteViewDep = self.viewDep as? SKView
                    self.spriteViewDep!.presentScene(sceneDep)
                    let metarShowSelectorDep : Selector = #selector(IGAAirportVC.showMetarReportDep)
                    let tapGestureDep = UITapGestureRecognizer(target: self, action: metarShowSelectorDep)
                    tapGestureDep.numberOfTapsRequired = 1
                    self.viewDep.addGestureRecognizer(tapGestureDep)
                }
           
                if self.spriteViewDest == nil
                {
                    let sceneDestWidth = self.viewDest.bounds.size.width
                    let sceneDestHeight = self.viewDest.bounds.size.height
                    let sceneDestSize = CGSizeMake(sceneDestWidth, sceneDestHeight)
                    let sceneDest = IGAAirportDestinationScene(size: sceneDestSize)
                    self.spriteViewDest = self.viewDest as? SKView
                    self.spriteViewDest!.presentScene(sceneDest)
               
                    let metarShowSelectorDest : Selector = #selector(IGAAirportVC.showMetarReportDest)
                    let tapGestureDest = UITapGestureRecognizer(target: self, action: metarShowSelectorDest)
                    tapGestureDest.numberOfTapsRequired = 1
                    self.viewDest.addGestureRecognizer(tapGestureDest)
                }
           
                if self.spriteViewAlt == nil
                {
                    let sceneAltWidth = self.viewAlt.bounds.size.width
                    let sceneAltHeight = self.viewAlt.bounds.size.height
                    let sceneAltSize = CGSizeMake(sceneAltWidth, sceneAltHeight)
                    let sceneAlt = IGAAirportAlternateScene(size: sceneAltSize)
                    self.spriteViewAlt = self.viewAlt as? SKView
                    self.spriteViewAlt!.presentScene(sceneAlt)
               
                    let metarShowSelectorAlt : Selector = #selector(IGAAirportVC.showMetarReportAlt)
                    let tapGestureAlt = UITapGestureRecognizer(target: self, action: metarShowSelectorAlt)
                    tapGestureAlt.numberOfTapsRequired = 1
                    self.viewAlt.addGestureRecognizer(tapGestureAlt)
                }
           
            dispatch_async(dispatch_get_main_queue())
                {
                    self.activityIndicator.stopAnimating()
                    self.btnMetar.enabled = true
                    self.btnWindAloft.enabled = true
            }
        }
    }

Then I have three classes for each of the scene that are similar. So, when I open the UIViewController, the activity indicator starts spinning until the scenes are loaded. It works except for the scene when I do the following:


func createSceneContents()
    {
        self.backgroundColor = SKColor.blueColor()
        self.scaleMode = SKSceneScaleMode.AspectFit
        addChild(airportNode())
    
          // NOT WORKING PROPERLY!
        if (appSingleton.metarReportDepShared == "" ||
            appSingleton.metarReportDepShared == "N/A")
        {
            noMetarNode()
        }
        
        else
        {
               ... WORKING...
        }
}

func noMetarNode()
    {
        let noMetarNode = SKLabelNode(fontNamed: "HelveticaNeue-Ultralight")
        noMetarNode.text = "N/A"
        noMetarNode.name = "nodeNoMetarDep"
        noMetarNode.fontColor = SKColor.whiteColor()
        noMetarNode.fontSize = 120
        noMetarNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
     
        self.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRectMake(60, 20, self.frame.size.width-120, self.frame.size.height-150))
        self.physicsBody?.friction = 0
        self.physicsBody?.categoryBitMask = self.frameCategory;
        self.physicsWorld.speed = 0.3;
        physicsWorld.gravity = CGVectorMake(0, 0)
     
        noMetarNode.physicsBody = SKPhysicsBody(circleOfRadius: 35)

        noMetarNode.physicsBody?.categoryBitMask = self.labelCategory;
        noMetarNode.physicsBody?.collisionBitMask = self.frameCategory;
        noMetarNode.physicsBody?.restitution = 1.0;
        noMetarNode.physicsBody?.friction = 0.0;
        noMetarNode.physicsBody?.linearDamping = 0.0;
        noMetarNode.physicsBody?.angularDamping = 0.0;
     
        addChild(noMetarNode)
     
        let impulse = CGVectorMake(5,5);
        noMetarNode.physicsBody?.applyImpulse(impulse)
     
        print("NO METAR 1")
    }

When the NoMetarNode() is implemented, the activity indicator does not show up spinning. Instead, the application lags for a few seconds waiting for the scenes to load and opens the scenes when they are loaded. I even see "NO MEATAR 1" text in the Console popping up immediately when I tap on a button. But the UIViewController does not open with a view indicator, as it does with other scenes.


Is there anything wrong with the code that I am missing? Thank you so much!


EDIT:


I am about to give up on this and implement the following when button is tapped to open a new UIViewController:


@IBAction func openMetar(sender: UIButton)
    {
        self.activityIndicator.startAnimating()
        performSelectorInBackground(#selector(IGAFlightplanVC.openMetarView), withObject: self)
    }
   
    func openMetarView()
    {
        performSegueWithIdentifier("segueMetar", sender: self)
    }


And stop the activity indicator in ViewWillAppear(). Or is there a better way?

Replies

How are you testing that this manifests?


Which devices? Release or debug?