I have the following code to convert RGB to HSV. This uses UIColor which is part of the UIKit. UIKit is not available in macOS. What is the alternative to do this in macOS?
func getHue(red: CGFloat, green: CGFloat, blue: CGFloat) -> CGFloat
{
let color = UIColor(red: red, green: green, blue: blue, alpha: 1)
var hue: CGFloat = 0
color.getHue(&hue, saturation: nil, brightness: nil, alpha: nil)
return hue
}
In macOS, use NSColor instead UIColor.
func getHue(red: CGFloat, green: CGFloat, blue: CGFloat) -> CGFloat{
let color = NSColor(red: red, green: green, blue: blue, alpha: 1)
var hue: CGFloat = 0
color.getHue(&hue, saturation: nil, brightness: nil, alpha: nil)
return hue
}
You should be using NSColor on macOS instead of UIColor. The two are similar, though NSColor allows for better color management, should you need it. It includes a similar getHue(_, saturation, brightness, alpha) method.
I would implement this a bit differently:
import AppKit
extension NSColor {
var hsba: (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) {
var hue: CGFloat = 0
var saturation: CGFloat = 0
var brightness: CGFloat = 0
var alpha: CGFloat = 0
self.getHue(
&hue,
saturation: &saturation,
brightness: &brightness,
alpha: &alpha
)
return (hue, saturation, brightness, alpha)
}
}
This lets you easily access not just the hue, but the satuation, brightness and alpha as well. And it doesn't require you manually provide 3 seperate rgb components. You can just call it on any existing NSColor instance. You might initialize one using rgb components, but you could also use any other other NSColor instance, such as one returned by another API, or one of the static value like NSColor.blue).
print(NSColor.green.hsba.hue)
Related
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)
I am following Stanfords' CS193p Developing Apps for iOS online course.
I'm trying to do the Assignment 6 Memorize.pdf.
It says to use this code below ⬇️, but it gives me always white color. Is there a bug somewhere? Please help.
import SwiftUI
struct RGBAColor: Codable, Equatable, Hashable {
let red: Double
let green: Double
let blue: Double
let alpha: Double
}
extension Color {
init(rgbaColor rgba: RGBAColor) {
self.init(.sRGB, red: rgba.red, green: rgba.green, blue: rgba.blue, opacity: rgba.alpha)
}
}
extension RGBAColor {
init(color: Color) {
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
if let cgColor = color.cgColor {
UIColor(cgColor: cgColor).getRed(&red, green: &green, blue: &blue, alpha: &alpha)
}
self.init(red: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha))
}
}
import SwiftUI
struct ContentView: View {
static let rgbaColorRed = RGBAColor(color: Color.red)
static let thisShouldBeRed = Color(rgbaColor: rgbaColorRed)
var body: some View {
Text("Hello, world!")
.padding()
.foregroundColor(ContentView.thisShouldBeRed) // why white here, not red???
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
As the cgColor property's documentation says:
For a dynamic color, like one you load from an Asset Catalog using init(_:bundle:), or one you create from a dynamic UIKit or AppKit color, this property is nil.
Color.red is actually a dynamic color:
A context-dependent red color suitable for use in UI elements.
So Color.red.cgColor is nil, causing the getRed(_:green:blue:alpha:) call to not run, and the red, green, blue, alpha local variables remain 0. So the color you got is not "white", but "transparent".
You can actually create a UIColor directly from Color, without going through CGColor:
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
// note here:
UIColor(color).getRed(&red, green: &green, blue: &blue, alpha: &alpha)
self.init(red: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha))
I am trying to change the text colour in a UITextField using the following code (RGBA value) however it just appears white, or clear, I'm not too sure as the background is white itself.
passwordTextField.textColor = UIColor(red: CGFloat(202.0), green: CGFloat(228.0), blue: CGFloat(230.0), alpha: CGFloat(100.0))
passwordTextField.returnKeyType = UIReturnKeyType.Done
passwordTextField.placeholder = "Password"
passwordTextField.backgroundColor = UIColor.clearColor()
passwordTextField.borderStyle = UITextBorderStyle.RoundedRect
passwordTextField.font = UIFont(name: "Avenir Next", size: 14)
passwordTextField.textAlignment = NSTextAlignment.Center
passwordTextField.secureTextEntry = true
RGB values for UIColor are between 0 and 1 (see the documentation "specified as a value from 0.0 to 1.0")
You need to divide your numbers by 255:
passwordTextField.textColor = UIColor(red: CGFloat(202.0/255.0), green: CGFloat(228.0/255.0), blue: CGFloat(230.0/255.0), alpha: CGFloat(1.0))
Another thing, you don't need to create CGFloats:
passwordTextField.textColor = UIColor(red:202.0/255.0, green:228.0/255.0, blue:230.0/255.0, alpha:1.0)
Using convenience init ( code like a pro )
Step 1
extension UIColor {
convenience init(r: CGFloat, g: CGFloat, b: CGFloat) {
self.init(red: r/255, green: g/255, blue: b/255, alpha: 1)
}
}
Usage
//let color = UIColor(red: 202/255, green: 228/255, blue: 230/255, alpha: 1) ☠️
let color = UIColor(r: 202, g: 228, b: 230) // 😍
try this instead :
passwordTextField.textColor = UIColor(red: 0.792, green: 0.894, blue: 0.901, alpha: 1.0
Always put substituted values. 202/255 = 0.792
red, green, blue and alpha are supposed to be between 0.0 and 1.0.
As others mentioned, UIColor components are normalized in the range 0.0 ~ 1.0 (I think wide color gamuts are the exception, but haven't researched that yet).
A conveninet extension to the UIColor class will let you use values in the 0~255 range (like those obtained from various inspectors and image editing tools):
import UIKit
extension UIColor {
convenience init(
redByte red:UInt8,
greenByte green:UInt8,
blueByte blue:UInt8,
alphaByte alpha:UInt8
) {
self.init(
red: CGFloat(red )/255.0,
green: CGFloat(green)/255.0,
blue: CGFloat(blue )/255.0,
alpha: CGFloat(alpha)/255.0
)
}
}
UIColor convenient methods, from Integers, or from Hex.
extension UIColor {
convenience init(red: Int, green: Int, blue: Int, alpha: CGFloat) {
assert(red >= 0 && red <= 255, "Invalid red component")
assert(green >= 0 && green <= 255, "Invalid green component")
assert(blue >= 0 && blue <= 255, "Invalid blue component")
self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: alpha)
}
convenience init(rgb: Int, alpha: CGFloat = 1) {
self.init(
red: (rgb >> 16) & 0xFF,
green: (rgb >> 8) & 0xFF,
blue: rgb & 0xFF,
alpha: alpha
)
}
}
Right now I can make it one of the given xcode color like black, blue, red, etc. However, I want to make it a specific color, aqua to be exact. Can anyone help me?
button1Label.setTitleColor(.blue, for: .normal)
Anyone have any suggestions? Thanks!
You need to define your Color by
UIColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
So it will be:
let yourColor = UIColor(red: 165.0/255.0, green: 170.0/255.0, blue: 178.0/255.0, alpha: 1.0)
button1Label.setTitleColor(yourColor, for: .normal)
You can use the RGB function of UIColor like so:
button1Label.setTitleColor(UIColor(red: 0/255, green: 255/255, blue: 255/255, alpha: 1), for: .normal)
Creating a custom UIColor Object. In Swift, you instantiate a custom UIColor object with an initializer.
There are several available to us, some more useful than others:
init(white: CGFloat, alpha: CGFloat)
init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha:
CGFloat)
init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
init(CGColor cgColor: CGColor!) init(patternImage image: UIImage)
init(CIColor ciColor: CIColor)
You can easily use RGB colors.
This is my favorite way of doing it with Swift
extension UIColor {
convenience init(rgb r: Int, _ g: Int, _ b: Int, _ a: CGFloat = 1) {
self.init(red: CGFloat(r)/255, green: CGFloat(b)/255, blue: CGFloat(b)/255, alpha: a)
}
}
and call it with
let color = UIColor(rgb: 150, 135, 85)
let color2 = UIColor(rgb: 100, 120, 200, 0.5)
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)
}