8 Replies
      Latest reply on Jan 30, 2016 5:45 PM by sez
      techspaghetti Level 1 Level 1 (0 points)

        Hi All.

         

        I've been experimenting with Xcode 7 and the updated SpriteKit Editor. For our current project we wish to design as much of the interface as possible visually. As there is no SKButton, I've created a simple Button class which extends SKSpriteNode

         

        import SpriteKit
        
        class Button: SKSpriteNode
        {
            // MARK: Init
            init(texture: SKTexture, size: CGSize)
            {
                super.init(texture: texture, color: UIColor.whiteColor(), size: size)
                userInteractionEnabled = true
            }
        
            required init?(coder aDecoder: NSCoder)
            {
                super.init(coder: aDecoder)
                userInteractionEnabled = true
            }
        
            // MARK: User Interaction
            override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
            {
                print("Button touchesBegan")
            }
        
            override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?)
            {
                print("Button touchesMoved")
            }
        
            override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?)
            {
                print("Button touchesEnded")
            }
        
            override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?)
            {
                print("Button touchesCancelled")
            }
        }
        
        

         

        and a simple GameScene.sks file which contains a single, colored SKSpriteNode named button.

         

        Now in GameScene.swift I can get a reference to this SKSpriteNode and cast it as a Button (regardless if a custom class is mentioned in the inspector panel or not).

         

        let button = self.childNodeWithName("button") as! Button
        

         

        Everything works perfectly fine when running on iOS 9, but on iOS 8 I receive the error

         

        Could not cast value of type 'SKSpriteNode' to 'buttonTestProject.Button'
        

         

        I am aware that the ability to assign a custom class in SpriteKit Editor is new in Xcode7, but the ability to cast a SKSpriteNode to a subclass surely isn't.

         

        An ugly work-around is that the visual SKSpriteNode can be used as a placeholder to create a Button

         

        let button: Button!
        if #available(iOS 9, *)
        {
          button = self.childNodeWithName("button") as! Button
        }
        else
        {
          let node = self.childNodeWithName("button") as! SKSpriteNode
          button = Button(texture: node.texture!, size: node.size)
          button.position = node.position
          node.removeFromParent()
          addChild(button)
        }
        

         

        Any feedback would be greatly appreciated. I know that from the .sks file the NSCoder init method is called, but I don't see what could be different there for iOS 8. I suppose the issue is that Editor supports custom classes for iOS 9 onwards. Any alternative methods would be greatly appreciated also Thanks!