Create a class of Colors - swift

In my app, I have for example 5 available colors for different Task that user can choose between them anytime. I thought it would be good to have a class of color and I declare few colors inside the class that in any controller I can access to those colors as an Array. For example when I want to show the colors to pickup, I want them as an array. But I don't know how to do that? I create a class but in the init part, I don't know how to add colors
final class Colors {
var color : [UIColor]
init(color: [UIColor]) {
}
}
Your help will be appreciated.

Extend UIColor, make your colors static properties, and make your array a computed static property.

Option 1 - You can extend UIColor to list all of your colors and create an array:
extension UIColor {
struct GoTimeThemes {
static let firstColor = UIColor(red: 48.0/255.0, green: 35.0/255.0, blue: 174.0/255.0, alpha: 1.0)
static let secondColor = UIColor(red: 83.0/255.0, green: 160.0/255.0, blue: 263.0/255.0, alpha: 1.0)
static let thirdColor = UIColor(red: 146.0/255.0, green: 80.0/255.0, blue: 156.0/255.0, alpha: 1.0)
static var allColors: [UIColor] {
let colors = [firstColor, secondColor, thirdColor]
return colors
}
}
}
And call your array like so
let colors = UIColor.GoTimeThemes.allColors
Option 2 - You can put your colors in an Enum that conforms to CaseIterable:
enum ThemeColors: CaseIterable {
case firstTheme, secondTheme, thirdTheme
var color: UIColor {
switch self {
case .firstTheme:
return UIColor(red: 48.0/255.0, green: 35.0/255.0, blue: 174.0/255.0, alpha: 1.0)
case .secondTheme:
return UIColor(red: 83.0/255.0, green: 160.0/255.0, blue: 263.0/255.0, alpha: 1.0)
case .thirdTheme:
return UIColor(red: 146.0/255.0, green: 80.0/255.0, blue: 156.0/255.0, alpha: 1.0)
}
}
}
And call it with allCases to get a Collection:
ThemeColors.allcases //→ [firstTheme, secondTheme, thirdTheme]

I thought it would be good to have a class of color and I declare few colors inside the class that in any controller I can access to those colors as an Array.
An enumeration would work well for this. The set of colors is fixed, right? It sounds like you won't need distinct instances of the set of colors, and it'd probably be nice to be able to access the colors without needing to create an object or bother with sharing an object. An enumeration gives you a set of discrete values, and it can have methods associated with it. For example, you could have a darkGreen value, and then methods like uiColor() and cgColor() that return UIColor and CGColor objects that correspond to that value.

Related

How to set alpha for an Assets Color in Swift

I just wanted to know how to change the opacity (alpha) of an asset color I have. When I try this UIColor(named: "something", alpha: 0.4), Xcode complains: Extra argument 'alpha' in call.
Is there any way I can modify the opacity of an asset color programmatically?
UIColor, as mentioned by Jasur S., has the withAlphaComponent(_:).
It can be used with any UIColor objects to modify its alpha:
let color = UIColor(named: "something")?.withAlphaComponent(0.5)
Creating custom extensions to cover existing functionality is an arguable good.
You can add this extension for UIColor and easy to use.
extension UIColor {
convenience init?(named: String, alpha: CGFloat) {
if let rgbComponents = UIColor(named: named)?.cgColor.components {
self.init(red: rgbComponents[0], green: rgbComponents[1], blue: rgbComponents[2], alpha: alpha)
} else {
self.init(named: named)
}
}
}
Usage:
let colorWithAlpha = UIColor(named: "Assets Color", alpha: 0.5)
You can set color alpha component when you assign color as follows:
button.backgroundColor = .black.withAlphaComponent(0.5)
You can modify asset color from here
Select that particular asset color and
Drag that opacity indicator in left or right or directly set some values
Use this extension to get the rgb value from the UIColor
extension UIColor {
var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
getRed(&red, green: &green, blue: &blue, alpha: &alpha)
return (red, green, blue, alpha)
}
}
Then you can create a new color
let assetColor = UIColor(named: "something")
let (r,g,b,_) = assetColor.rgba
let newColor = UIColor(red:r, green:g, blue:b, alpha: 0.4)

How to use UIColor as RawValue of an enum type in Swift

I was trying to declare an enum type using UIColor as the raw value. Here is the code:
enum SGColor: UIColor {
case red = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
case green = #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)
case purple = #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)
}
But I got two errors in the first line:
'SGColor' declares raw type 'UIColor', but does not conform to
RawRepresentable and conformance could not be synthesized
Do you want to add protocol stubs? Fix it
Raw type 'UIColor' is not expressible by any literal
If I took the first advice, Xcode will add typealias RawValue = <#type#> at the beginning inside of the parentheses. But I am not sure what to do with it.
And if I were to address the second error, how do I change the raw type to a literal?
After some digging, I found a post by Ole Begemann that mentions how to make a customized color enumeration collection, which is SGColor in this question, conform to the RawRepresentable protocol.
Basically, while Xcode is smart to suggest me to fix the problem by explicitly telling it the raw type (as seen in the first error in the question), it is still not intelligent enough to figure out how to do that for color literals, or UIColor.
Ole Begemann mentioned a manual conformance will fix this. And he gave a detailed explanation as of how to do it.
While he used UIColor color objects (such as UIColor.red), I tried and tested the feasibility of using color literals, since in general, they are more visually direct and more customizable.
enum SGColor {
case red
case green
case purple
}
extension SGColor: RawRepresentable {
typealias RawValue = UIColor
init?(rawValue: RawValue) {
switch rawValue {
case #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1): self = .red
case #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1): self = .green
case #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1): self = .purple
default: return nil
}
}
var rawValue: RawValue {
switch self {
case .red: return #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
case .green: return #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)
case .purple: return #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1)
}
}
}

Swift right CustomColor class declaration

because of strange color solutions in swift i needed to make customcolor class. And i dont know am i doing right.
i have a class CustomColors()
and usage: color = CustomColors().black and works perfectly
but i want to make use like: color = CustomColors(.Black)
i cant do like this:
init(_ Color: Colors)
{
switch Colors
case .Black
return UIColor(r:255,g:255,b:255,a:255)
}
A lot of things i dont know. Can someone put me on right solution? Thank you.
Instead of custom class you can use an UIColor extension with convenience initializer, as such:
extension UIColor {
convenience init(color: Colors) {
switch color {
case .black:
self.init(red: 1, green: 1, blue: 1, alpha: 1)
case .white:
self.init(red: 1, green: 1, blue: 1, alpha: 1)
}
}
}
But I think its better if you pre-define your colors using struct's static properties, as such:
struct Theme {
static let colorOne = UIColor(red: 0.952941, green: 0.952941, blue: 0.952941, alpha: 1.0) // F3F3F3
static let colorTwo = UIColor(red: 0.203922, green: 0.203922, blue: 0.203922, alpha: 1.0) // 343434
// and so on...
}
Usage
UILabel().backgroundColor = Theme.colorOne
UILabel().textColor = Theme.colorTwo
you can add extension to UIColor class with your custom colors:
import UIKit
extension UIColor {
static var mediumTurquoise: UIColor {
return UIColor(red:0.31, green:0.82, blue:0.8, alpha:1)
}
}
please be sure that the value of RGB between 0.0 and 1.0.
you can user the custom color as UIolor.mediumTurquoise

Swift - why NSColor becomes lighter when rendered

I've created NSWindow and made it's background colour absolutely blue (#0000FF). But when the window is rendered, the colour is "lighter" than it should be (#0F3FFB).
class LilWindow: NSViewController {
override func viewDidLoad() {
self.view.window?.backgroundColor =
NSColor.init(red: 0, green: 0, blue: 1, alpha: 1)
}
Does anyone know why it is happening and how to fix this? (screenshot attached)
Okay, so after a couple of hours fiddling with code and #KenThomases help, I figured out that if you want your RGB colours to looks correctly on NSImages and NSWindows, you must convert it into NSDeviceRGBColorSpace colorspace. To do this I've written a simple function:
func toScreenColor(color:NSColor) -> NSColor {
var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0
color
.colorUsingColorSpaceName(NSCalibratedRGBColorSpace)!
.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
return NSColor(deviceRed: red, green: green, blue: blue, alpha: alpha)
}

Swift: using member constant as default value for function parameter

I have a swift class, in which I am trying to pass a default value for a function parameter:
class SuperDuperCoolClass : UIViewController {
// declared a constant
let primaryColor : UIColor = UIColor(red: 72.0/255.0, green: 86.0/255.0, blue: 114.0/255.0, alpha: 1.0)
// compilation error at below line: SuperDuperCoolClass.Type does not have a member named 'primaryColor'
func configureCheckmarkedBullet(bullet: UIButton, color: UIColor = primaryColor){
// some cool stuff with bullet and primaryColor
}
}
As stated above, if I try to use constant as default value for function parameter, compiler complains with below error:
SuperDuperCoolClass.Type does not have a member named 'primaryColor'
but if I assign the RHS value directly like this, it does not complain :-/ :
func configureCheckmarkedBullet(bullet: UIButton, color: UIColor = UIColor(red: 72.0/255.0, green: 86.0/255.0, blue: 114.0/255.0, alpha: 1.0)) {
// now I can do some cool stuff
}
Any ideas on how can I silence the above compilation error?
You have to define the default value as a static property:
class SuperDuperCoolClass : UIViewController {
static let primaryColor : UIColor = UIColor(red: 72.0/255.0, green: 86.0/255.0, blue: 114.0/255.0, alpha: 1.0)
func configureCheckmarkedBullet(bullet: UIButton, color: UIColor = primaryColor){
}
}
The above code compiles with Swift 1.2 (Xcode 6.3) which added support
for static computed properties. In earlier versions, you can define
a nested struct containing the property as a workaround (compare
Class variables not yet supported):
class SuperDuperCoolClass : UIViewController {
struct Constants {
static let primaryColor : UIColor = UIColor(red: 72.0/255.0, green: 86.0/255.0, blue: 114.0/255.0, alpha: 1.0)
}
func configureCheckmarkedBullet(bullet: UIButton, color: UIColor = Constants.primaryColor){
}
}
Since primaryColor is an instance variable it cannot be accessed until an instance is created from this class and since the function is part of the class definition you will get this error as primaryColor cannot access at that time.
You can either use MartinR approach or use your approach with the desired color:
func configureCheckmarkedBullet(bullet: UIButton, color: UIColor = UIColor(red: 72.0/255.0, green: 86.0/255.0, blue: 114.0/255.0, alpha: 1.0)) {
// now I can do some cool stuff
}