SWIFT - Can I have a SKView as a subview of a UIView? - sprite-kit

In my storyboard, I have a base UIView, then a UIView containing a square board drawing in a CGRect and buttons and status fields above and below. I tried drawing the playing pieces but animating them became a nightmare so I have rendered them as sprite nodes in an array and they animate themselves. So far so good. Then layer on top of that is a SKView view and I want to present the SpriteKit scene in there with skView.allowsTransparency = true so I just have the sprites over a transparent background (revealing the board below) and using TapGestureRecognizers to effect the sprite animation event handling.
So in IB hierarchy is: VC / UIView / boardView: UIView / skView
Problem is, the Spritekit scene always targets the top level UIView not skView so game pieces are behind the board. Am I missing something simple here?
I'm gonna try placing a child VC where skView is but any assist, if I've missed a trick, would be very much appreciated.

I wish I could see some code, but what you do is create an IBOutlet for your SKView, then have that outlet present the scene, I am currently doing this in an app I am working on, so I know it is doable

Related

Add a Sprite Kit View to a UIView Xcode 8.2.1

I am making a app that will hopefully have a game in it but in order to do that I need a Sprite Kit View. I was wondering if there was a way to add a Sprite Kit View to a Single View Application?
Yes, SKView is just a subclass of UIView, so you can add it via code where you want or through the Storyboard. as of XCode 9 I believe, IB allows you to add an actual SKView where you can set the scene file instead of having to fill the custom class field in.

SpriteNode behind UIImages

I've created a SpriteNode in a scene and it's there, but it is stuck behind all the UIImages and UIButtons I've dragged onto the storyboard.
I tried changing the .zPosition of the spriteNode to 99999999999999, but it doesn't matter.
What do I need to do to get the spriteNode to appear in front of most of the images? Or can I only have one background image?
Unfortunately for you, this is impossible. You are combining two rendering hierarchies (UIKit and Sprite Kit) whose children (UIView and SKNode, respectively) do not mingle.
SKNodes are rendered inside the SKScene that contains them. The final rendered image is used as the image for the layer of the owning SKView. From there, UIKit (and CoreAnimation) composite the UIViews.
A hierarchy for illustration purposes:
UIView
UIButton
UIButton
SKView (renders an SKScene object)
SKNode
SKLabelNode
SKLabelNode
UIImageview

How to present a view on top of SKScene?

I know there is many question out there on the same topic but still I didn't get any idea or solution to make it work. How do I implement a small view on top of a scene with options as shown in image?
You can do it within your scene using spritekit nodes or you can create a UIView from your viewController and add it the viewControllers view:
something like this:
// set up base view of the game
self.baseView = UIView(frame: self.view.frame)
self.view.addSubview(self.baseView)
// add my skView to my baseView
self.baseView.addSubview(skView)
// add pause button on top or other elements
// hide or show these as needed
self.baseView.addSubview(self.pauseBtn)
self.addJoySticks()
You could just use SpriteKit itself and:
scene?.view?.presentScene(anotherScene, transition: SKTransition.fadeWithDuration(1.0))
edit Just to add, If any Background AVPlayers or nodes are in play, then they're all discarded when transitioning.

How to place sprite kit elements overtop of regular UIKit elements

I'm trying to geive the user the ability to drag a skspritenode over a UIImageView and UIButton, but whenever I create the scene it appears behind the UI elements. How do I fix this?
I am afraid that is just not possible. All the sprites and any other elements are rendered frame by frame on the SKScene node and cannot be "dragged" or placed anywhere else. These are not UIKit elements.
In this case, your view is acting as the SKScene and hence all the sprites are being rendered onto that.
SKView is a UIView/NSView in itself. All the Sprite Kit nodes (the scene is also a node) are constituents of the SKView and contained within it. You can only change the draw order of views but not their contents.
To give an example: what you're trying to do is the equivalent of trying to place a UIImageView on top of a UIButton's background but below the UIButton's label.
While technically you could achieve this for plain UIView elements with some trickery, the same will never work for Sprite Kit nodes. They aren't views to begin with but drawn onto an OpenGL framebuffer represented/managed by the SKView. From the perspective of Cocoa an SKView is a single view with no subviews in it.
Simply put: nodes are not views, and nodes are technically incompatible to views.
The UIImageView and its UIButton and whatever other content you want in there must be in a UIView that's sitting lower than the SKView you have the Sprite Kit contents in.
And you'll need to ensure the SKView is transparent (at least its background) and that it passes touches through to the UIView underneath if you need them down there sometimes.

Is it possible to add a SpriteKit scene with transparent BG on top of a uikit view hierarchy?

I'd like to take advantage of the particle effects (and maybe some other stuff) in SpriteKit but my app is mainly rooted in UIKit. Does the SpriteKit framework allow you to create a scene with a transparent background that I can place on top of my UIKit view hierarchy?
Short answer is no.
You can add SKView (subclass of UIView) to your view hierarchy, and set its scene to your own SKScene. But SKView has a backgroundcolor property that cannot be clear (defaults to grey).
It seems possible in OSX mavericks, so hopefully apple will add this possibility in iOS as well.
If your app is mainly rooted in UIKit, Sprite Kit probably isn't the best way to get spiffy visual effects. Some alternatives:
Core Animation provides a particle system in the CAEmitterLayer class.
UIKit has dynamic, physics-based behaviors for animating UI elements.
As of iOS 8, Apple has added this ability: see SKView.allowsTransparency.
https://developer.apple.com/documentation/spritekit/skview/1519697-allowstransparency
It defaults to false, yielding the black rectangle background you see; but set it to true, set its background color to .clear, and it composites over UIKit content just fine.
Further info: Removing Background of SKView - Particle Emitter - SpriteKit