How to update SKLabelNode color after the node is initiated? - swift

I have SKLabelNode in my Swift-code. I need to change the Label's color during SKAction. Simply:
override func didMoveToView(view: SKView) {
...
var color = UIColor(red: CGFloat(1.0), green: CGFloat(0.0), blue: CGFloat(0.0), alpha: CGFloat(0.0))
myLabel.fontColor = color
...
}
Doesn't work. I still have to somehow update the node but how? I'm noobie to Swift and Sprite Kit.

Do you need it to be in an SKAction? If not, simply use this:
myLabel.fontColor = SKColor.blueColor()
Substitute blueColor with whichever color you want, or use the generic method where 'float here' is a fraction of 255 (such as 50.0f/255.0f).
myLabel.fontColor = SKColor(red: floatHere, green: floatHere, blue: floatHere, alpha: floatFrom0To1Here)
In case you do need to set the color through an SKAction, you can use this method:
myLabel.runAction(SKAction.colorizeWithColor(UIColor.blueColor(), colorBlendFactor: 1, duration: 1))

I had a similar problem a few weeks ago.
Try changing your color variable to the following:
var color = UIColor(red: 1.0 / 255, green: 0.0 / 255, blue: 0.0 / 255, alpha: 0.0)

Related

SKLightNode with flat shape

Does anyone knows what could affect the "shape" for a SKLightNode?
In a Playground project, I added 2 lights: one for the ambiant light (located of the scene) and one for a local light (located on scene) and the "shape" of the light in nice and round like here:
But adding the same code in another project, the light is having a flat shape like this:
In both cases, the light is added as part of the SKScene and I change the colour with this:
backgroundLightNode.ambientColor = NSColor(red: 1.0, green: 1.0, blue: 1.0, alpha: alpha)
lightNode.lightColor = NSColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1 - alpha)

Type 'NSColor' has no member 'black'

I'm working with Swift and SceneKit in Xcode 9.2. I've been applying color to geometry with NSColor, but all of a sudden (gradually) most of my colors get the type NSColor has no member .colorname. Like my game compiled and ran just fine, and then on the next compile, I got an error with .cyan. I changed it to .black and it ran. Then another color got an error, and then most of the colors got an error.
Here's an example:
node.geometry?.firstMaterial?.diffuse.contents = NSColor.black
the options that I have left are:
.blue, .green, .int, .rawValue, .red, .yellow.
What happened to all the colors?
EDIT: I cleaned up the project, it all compiles without warnings but I still only have 4 colors and they all render gray. I printed out the nodes diffuse colors to console and they read correct.
I've also imported Cocoa framework.
EDIT: I FOUND MY MISTAKE.
I accidentally replaced the name of an enum with NSColor while doing a find and replace. That's why SKColor worked, because it was a new name.
I am so embarrassed.
You could use:
node.geometry?.firstMaterial?.diffuse.contents = NSColor(srgbRed: 0, green: 0, blue: 0, alpha: 1.0)
In this way you create a color with your own RGBs values, so in this way you can get the color black. The last parameter, alpha, is the value of opacity and it needs to be 100 in order to see the color
In your case the better way is to use this syntax:
NSColor(calibratedRed: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
In iOS you should use the syntax like this:
cube.firstMaterial?.diffuse.contents = UIColor(red: 0.3, green: 0.45, blue: 0.75, alpha: 1.0)
In macOS the syntax is like this:
sphere.firstMaterial?.reflective.contents = NSColor(calibratedRed: 99.0, green: 0.0, blue: 0.0, alpha: 1.0)
Remember, the alpha (aka opacity), specified as a value from 0.0-1.0. Alpha values below 0 are interpreted as 0.0, and values above 1.0 are interpreted as 1.0.
And, of course, you can specify the colorspace explicitly (like sRGB):
init(srgbRed: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)

Converting CGFloat, CGFloat, CGFloat into UIColor?

I have an array of colours that look like this...
var purpleShades: [(CGFloat, CGFloat, CGFloat)] = [(186.0/255.0, 85.0/255.0, 211.0/255.0), (147.0/255.0, 112.0/255.0, 219.0/255.0), (138.0/255.0, 43.0/255.0, 226.0/255.0), (148.0/255.0, 0.0/255.0, 211.0/255.0), (153.0/255.0, 50.0/255.0, 204.0/255.0), (139.0/255.0, 0.0/255.0, 139.0/255.0)]
rather than duplicate code was wondering if anyone could help convert it to UIColor, so I can use it for this piece of code.
cell.tintColor = grayShades[Int(index)]
This variation of init might help you
It accepts red, green, blue and alpha as parameters.
Here's a nice extension to UIColor:
extension UIColor {
convenience init(hex: UInt, alpha: CGFloat) {
var red, green, blue: UInt
red = ((hex & 0xFF0000) >> 16)
green = ((hex & 0x00FF00) >> 8)
blue = hex & 0x0000FF
self.init(red: CGFloat(red) / 255, green: CGFloat(green) / 255, blue: CGFloat(blue) / 255, alpha: alpha)
}
}
With that you can write:
let purple = UIColor(hex: 0x9932CC, alpha: 1)
If you have a lot of colours, another extension on UIColor gives you…
extension UIColor {
static let darkOrchid = UIColor(hex: 0x 9932CC, alpha: 1)
static let darkMagenta = UIColor(hex: 0x 8B008B, alpha: 1)
static let indigo = UIColor(hex: 0x 4B0082, alpha: 1)
}
which allows you to say, for example…
cell.tintColor = .darkOrchid

Getting hue from UIColor yields wrong result

I'm doing the following in order to retrieve the hue from a UIColor():
let rgbColour = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
var hue: CGFloat = 0
var saturation: CGFloat = 0
var brightness: CGFloat = 0
var alpha: CGFloat = 0
rgbColour.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
println("\(hue),\(saturation),\(brightness)")
Output:
1.0,1.0,1.0
According to this link, I'm meant to be getting 0.0,1.0,1.0 for RGB (red) 1.0,0.0,0.0.
Am I doing something wrong?
First of all the range of the red/green/blue components in UIColor is 0.0 .. 1.0,
not 0.0 .. 255.0, so you probably want
let rgbColour = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
But even then you get the output 1.0,1.0,1.0 and this is correct.
The hue component ranges from 0.0 to 1.0, which corresponds to the angle from 0º to 360º
in a color wheel (see for example HSL and HSV).
Therefore hue = 0.0 and hue = 1.0 describe an identical color.
If you need to normalize the hue component to the half-open interval
0.0 <= hue < 1.0 then you could do that with
hue = fmod(hue, 1.0)
To build on #Martin R's answer:
If you wanted to use HSB, you need to:
Divide the hue value by 360
Use decimals for the Saturation and Brightness values
So, say for example that Sketch is telling you the colour values in HSB are: Hue: 20, Saturation: 72 and Brightness: 96
In Xcode, create the colour as follows:
let myAwesomeColour = UIColor(hue: 20/360, saturation: 0.72, brightness: 0.96, alpha: 1.0)
Whether you use RGB or HSB is a matter of preference. The results are the same as far as Xcode is concerned, they both translate to a UIColor.

UIButton Borders Function Only Gives Back White Borders

I'm trying to create a Button Borders Function in Swift to help style my UI. However whatever RGB values I pass in/initialize the function only creates white borders.
Here is my function:
func buttonsWithBorders(button: UIButton, borderWidth: CGFloat, redcolour: CGFloat , greencolour: CGFloat, bluecolour: CGFloat, alpha: CGFloat?) {
let redcolour : CGFloat = 7.0
var greencolour : CGFloat = 3.0
var bluecolour : CGFloat = 2.0
var alpha: CGFloat = 1.0
var widthOfBorder: CGFloat = borderWidth
var theButtonWithBorders: UIButton
var buttonBorderColour : UIColor = UIColor(red: redcolour, green: greencolour, blue: bluecolour, alpha: alpha)
button.layer.borderWidth = widthOfBorder
return button.layer.borderColor = buttonBorderColour.CGColor
}
And I call it using:
buttonsWithBorders(learnHomeButton, 2.0,2.0, 5.0, 5.0, 1.0)
Also I know that passing in values and initializing them is incorrect but Xcode complaines that I am not initializing before using them otherwise
Any help would be very much appreciated, Cheers
You aren't initializing them. You're declaring entirely new variables with the same names as the parameters you're passing in. Whenever you use let or var you are introducing a brand new variable.
When a new variable is introduced with the same name as another currently in scope, this is known as variable shadowing, and what you have here is an almost textbook case.
A better, more concise implementation of your function might look like this:
func addButtonBorder(button: UIButton, width: CGFloat, red: CGFloat, blue: CGFloat, green: CGFloat, alpha: CGFloat = 1.0) {
button.layer.borderColor = UIColor(red: red, green: green, blue: blue, alpha: alpha).CGColor
button.layer.borderWidth = width
}
I used a different name because buttonsWithBorders implies that one or more buttons will be returned from this function. That does not appear to be your intent. Since you are passing one button in, you could only ever get one out, but "buttons" implies more than one.
If I were going to initialize a lot of buttons with borders, I might do something like this:
extension UIButton {
convenience init(frame: CGRect, borderColor: UIColor, borderWidth: CGFloat = 1.0) {
self.init(frame: frame)
setBorder(borderColor, borderWidth: borderWidth)
}
func setBorder(borderColor: UIColor, borderWidth: CGFloat = 1.0) {
layer.borderWidth = borderWidth
layer.borderColor = borderColor.CGColor
}
}
Then you could say UIButton(frame: frame, borderColor: borderColor, borderWidth: 2.0) to initialize a new button or button.setBorder(borderColor, borderWidth: 2.0) to set the border on an existing button.
UIColor takes a float between 0 and 1. So you want to divide your RGB Values by 255.0
Here is the code I used, that works on playground :
import Foundation
import UIKit
func buttonsWithBorders(button: UIButton, borderWidth: CGFloat,
redcolour:CGFloat, greencolour:CGFloat, bluecolour:CGFloat,
alpha:CGFloat) {
let buttonBorderColour : UIColor = UIColor(red: redcolour, green: greencolour, blue: bluecolour, alpha: alpha)
button.layer.borderWidth = borderWidth
return button.layer.borderColor = buttonBorderColour.CGColor
}
let learnHomeButton = UIButton(frame: CGRect(x: 0, y: 0, width: 50,
height: 50))
buttonsWithBorders(learnHomeButton, 2.0, 177/255.0, 177/255.0,
177/255.0, 1.0)
I edited the code so you can pass the colors to the function as parameters. Hope it helps.
The colour values need to be between 0.0 and 1.0 so you should define them as:
let redcolour : CGFloat = 7.0 / 255.0
var greencolour : CGFloat = 3.0 / 255.0
var bluecolour : CGFloat = 2.0 / 255.0