In my app, for one screen, I am setting the size and centering the background of a SpriteKit node. For example, I'm setting the size of the background subview as follows:
backgroundNode.size = self.frame.size
While this is working on the iPhone 6 Plus, the smaller screen/lower resolution of the iPhone 5 means the default size of the other nodes makes is too large to fit within their scene.
How can I force other nodes conform to the size of the background node? I wanted to divide each subview's size by the background subview's size, but math operations can't be done directly on the size property.
SpriteKit scenes (SKScene
) contain nodes, nodes (SKNode
), which have size
and position
properties (of type CGSize
and CGPoint
, respectively).
UIKit UIView
.frame
and bounds
properties are a CGRect
structs comprised of the same CGSize
and CGPoint
type structs.
So it really helps to understand how to work with CGRect
, CGSize
and CGPoint
.
Be aware, CGRect
, CGSize
and CGPoint
as structs, in Swift, are always passed by value to functions, not by references as classes are, so you can't modify fields inside the structs passed into a function, and have them propagate back to the caller's copy of the struct without taking extra steps.
Because size and position properties are compound types, you can't use them like scalars in simple in math and logic operations; as they contain multiple properties.
For example:
CGSize
contains width
and height
properties,CGPoint
consists of x
and y
properties.If want to divide size, you have to access width and height properties of the CGSize
struct individually.
You can assign the size in one operation (i.e. single constructor):
node.size = CGSize(
width: node.size.width / backgroundNode.size.width,
height: node.size.height / backgroundNode.size.height)
Or you could do it discretely:
node.size.width = node.size.width / backgroundNode.size.width
node.size.height = node.size.height / backgroundNode.size.height
When dealing with CGRect
fields, sometimes it's useful to deal with it as a single entity. For example,
view.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
Others sometimes it's more practical to set size
and origin
properties separately:
view.frame.origin = CGPoint (x: 0, y: 0)
view.frame.size = CGSize (width: 10, height: 10)
or even:
view.frame.origin.x = 0
view.frame.origin.y = 0
view.frame.size.width = 10
view.frame.size.height = 10
It's also worth knowing about the "zero" static property of each of the struct, as convenient crisp shorthand equivalents:
CGRect .zero ... CGRect (x: 0, y: 0, width: 0, height: 0)
CGPoint.zero ... CGPoint (x: 0, y: 0)
CGSize .zero ... CGSize (width: 0, height: 0)
If you do a lot of adjusting of size and position, to reduce code bloat, you might consider borrowing or developing convenient Swift extensions to `CGRect, CGSize and CGPoint` to simplify applying delta values to sizes or origins.