SKSpriteNode with a size relative to the screen - sprite-kit

I'm trying to create a 'modal' SKSpriteNode that fills most of the screen minus a border on each side. I have a subclass of SKSpriteNode as I need to pass some other info to it for display purposes, so I have a custom init method.
After I initialise my Modal I'm then setting the size as below:
let modal = Modal(items: [Item])
let newSize = CGSize(width: (frame.width) - 40, height: (frame.height) - 40)
modal.size = newSize
modal.zPosition = 999
addChild(modal)
The trouble is there is no border at the top or bottom on my Modal, it fills the entire screen vertically. My custom 'init' method of modal calls the super.init passing in a size of 50,50 so even that should be a lot smaller then the screen if that's what it was using but it's not. My game is in landscape mode and I tried switching the width and height above but that fills the entire screen (so there's no border on the left and right either). I know I've not set the position in the above code, but even then I would expect to see a 'border' somewhere evening if it isn't uniform.
This is all done in my main scene file, so frame here relates to the frame of the main game scene.
Any ideas?

So for anyone else has a similar issue the problem was that my scene was loaded from an SKS file.
The SKS file in question had it's size set to freeform. Changing this to a specific device e.g iPhone 6 and making sure the orientation was set to landscape has fixed the issues with sizing

Related

ARSCNView Corner Radius not showing

I have a corner radius on my ARSCNView as below;
override func viewDidLayoutSubviews() {
sceneView.layer.cornerRadius = 8
sceneView.layer.masksToBounds = true
sceneView.clipsToBounds = true
}
However, it is only showing when you enter app in background as illustrated below;
As soon as the app is in the foreground the corner radius goes back to 0.
Ive tried adding in ViewDidLoad & ViewWillAppear no success
I just tried with just
sceneView.layer.cornerRadius = 8
without masksToBounds and clipsToBounds and it worked for me.
If you're sceneView is inside another view or the root view of your view controller, check the background of that view and make sure it's something noticeable.
Maybe the sceneView itself is larger than the phones screen. Check the frame size or the layout constraints and make sure they are not causing the sceneView to stretch outside the phone screen edges.
I hope this answers your question.

How to prevent SpriteKit overlay in SceneKit to stretch?

In WWDC 2017 SceneKit session they recommend using overlaySKScene to overlay a SpriteKit layer over SceneKit for HUD, etc. It seems to work fine until I rotate the iPhone/iPad. Now the text in SpriteKit all got stretched (if turn from portrait to landscape) or shrunk (if turn from landscape to portrait). Is there anyway to keep the text or graphics in same size regardless of orientation?
sceneView.overlaySKScene = SKScene(size: sceneView.frame.size)
I solved the issue in a very simple way. Just resize the overlaySKScene and reposition everything in
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
let width = sceneView.frame.height
let height = sceneView.frame.width
sceneView.overlaySKScene?.size = CGSize(width:width, height:height)
...
}
Hope this helps others facing similar problem.
You need to look at how SKScene works:
This means set the overlay to size of the iphone screen for the given orientation:
sceneView.overlaySKScene = SKScene(size: sceneView.frame.size)
Now I am assuming nothing else changes, so that means your scaleMode is set to .fill, which means stretch graphics till all sides are filled in.
When sitting in portrait mode, you will not notice anything because it is 1:1 scale.
Now you flip it to landscape.
The system is going to attempt to convert your portrait screen size to a landscape size.
This means you are going to get fat stubby graphics because it is going to stretch out your sides, and shrink your top and bottom to fill all edges.
This is why doing code like sceneView.overlaySKScene = SKScene(size: sceneView.frame.size) is bad. You end up getting yourself confused.
I always recommend either using an SKS file, or setting a constant scene size, so sceneView.overlaySKScene = SKScene(size: CGSize(750,1334))
Then, depending on how I want to display my overlay, I use the proper scale mode.
In games where I want the overlay to take up the exact percentage of screen space, I use .aspectFill
In games where I want the overlay to take up the exact amount of pixel space, I use .resizeFill
By looking at the scaleMode, I now know how my scene is suppose to behave.
With .aspectFill, I am going to need to detect when orientation was flipped, and at that time either present the SKS corresponding to orientation, or move nodes corresponding to orientation.
With .resizeFill, I need to create a resize method that adheres to when the orientation is flipped, and move the nodes in proportion to the new size.
You can detect when orientation flips in the ViewController with
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
then use the view to get to the scene to call your resize function/load a new scene.

Subview not resizing proportionate to super view

I have a gameView(Just a blue color view with grid lines). I have pinned this gameView to the bottom and the sides of the screen and set the height to 475. When a user taps on this view, I locate the point and create a custom view(fenceView) with the origin and frame of the cell(width and height). In the init method of the fenceView I create a new UIImageView of a fence image and add it as a subview.
Because of autolayout, when the device is rotated, the width of the gameView changes accordingly. But the problem is, the added fenceViews do not resize. I tried to set the autoresizingMask = [.FlexibleWidth, .FlexibleHeight] for both the gameView and the fenceView. But it did not solve the issue.
We can see that in the landscape mode, the fence images are not displayed properly. It might be small mistake that I am doing, but I am not able to solve this issue since two days. Any help is greatly appreciated.
.FlexibleHeight does not need to be used since the overall height will always be 475. Try setting the autoresizingMask = [.FlexibleWidth, .FlexibleLeftMargin, .FlexibleRightMargin].
The width will need to change as well as its X position for the larger/smaller width. Both flexible Left and Right margin will apply the increased width to both sides.

iphone two nibs have different x coordinates for center

Ok this is really odd.
I didn't even know how to phrase the question.
I am using XCode 4.5
I have two views, each with their own NIB. It is possible that one NIB was created in a much earlier version of XCode, and one in 4.2 (I don't remember)
I have an icon that I want to center horizontally.
In one NIB, when I center it, the Frame Rectangle says X/Y coord = 160x46
which makes sense as its centered and near the top of the display
In the other NIB, the Frame rectangle is: X/Y coord = 204x46 yet it is also essentially centered (it's possible it is off by a few px)
If it set the Frame Rect to 160 x 46, then the icon moves way over to the left.
It's like Interface Builder thinks one NIB is wider/denser than the other
They are set to Size: None, Orientation: Portrait
View mode = Scale To fill.
I duplicated them both for Retina4 as I want to layout slightly differently, and the same problem occurs when I set the size to retina 4"
I cant see any settings where I could have messed this up .....
Do one thing dont change from XIB set it from code. For X value you can set
self.view.center.x
and for Y value
self.view.center.y

Flip Animation is not consistant in size between front and back images

using the same flip animation as in the Elements, I have a view controller flipping two .png files of the same size (640 x 960) Within each image I have drawn a border and have noticed that when I flip the image, the second image gets stretched slightly downward and you no longer see the bottom border.
I've checked my .xib file where I have two views and an imageview inside each view. The imageviews are both the same size and have the same settings. I did notice that in interface builder the size for the layout is 320 X 460. Note that the first view appears in its entirety and as I flip it over and over it continues to appear as it should and the other image is clipped.
It turns out that the first view presented to the window has a heeight of 416 and not 480 as expected. I forgot to account for the added NavBar and the initial view squashed my image to fit in its entirety. I have since set the view size in the back view and am dealing with the smaller image area.