How to Make a Swift Enum with Uicolor Value

How can I make a Swift enum with UIColor value?

I do it like this (basically using a struct as a namespace):

extension UIColor {
struct MyTheme {
static var firstColor: UIColor { return UIColor(red: 1, green: 0, blue: 0, alpha: 1) }
static var secondColor: UIColor { return UIColor(red: 0, green: 1, blue: 0, alpha: 1) }
}
}

And you use it like:

UIColor.MyTheme.firstColor

So you can have a red color inside your custom theme.

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

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)
}
}
}

Is there simple way to create UIColor extension for enum of UIColor with String raw data in Swift 3?

You could do it like this. Depends on how many colors you want to do this for. Not sure what you intend to do with this but it doesn't look like the most useful extension.

extension UIColor {
convenience init(_ colorString: ColorString) {
switch colorString {
case .red:
self.init(red:1.0, green:0.0, blue:0.0, alpha:1.0)
case .green:
self.init(red:0.0, green:1.0, blue:0.0, alpha:1.0)
case .blue:
self.init(red:0.0, green:0.0, blue:1.0, alpha:1.0)
}
}
enum ColorString: String {
case red
case green
case blue
}
}

Your conversion from colorString to UIColor would have to be of the form

let color = UIColor(array[1])

Declaring an enum to change color used in app for different type of users

I believe what you want is not possible. Enum may not be a class, only a generic type, a structure.

But it is usually not what you want as when you will have many of these values you will have a mess anyway. For instance at some point you will have a button background color, border color and text color. Then waht do you expect your result to be like:

button.backgroundColor = UIButton.backgroundColor
button.layer.borderColor = UIButton.borderColor.cgColor
button.label.textColor = UIButton.textColor

And now having 3 enums for a single component... It is a solution but I think it is a bad one...

I suggest you rather create a static class and have it like so:

class UserApperance {
static var userType: UserType = .admin

static var navigationTintColor: UIColor {
switch userType {
case .admin: ...
case .user: ...
}
}

}

So all you will do in the code is again

tabBarController.tabBar.barTintColor = UserApperance.navigationTintColor

And when you want to group them you can use nesting:

class UserApperance {
static var userType: UserType = .admin

class NavigationBar {
static var tintColor: UIColor {
switch UserApperance.userType {
case .admin: ...
case .user: ...
}
}
}


}

Where the result is now nicer:

tabBarController.tabBar.barTintColor = UserApperance.NavigationBar.tintColor

In my opinion this is the nicest way and with really hard situations like white-label applications you can really play around with nesting and do it per screen and even have code like:

let appearance =  UserAppearance.thisScreenName
titleLabel.textColor = appearance.title.textColor
titleLabel.font = appearance.title.font

Bot to mention you can generalize some things and even have usage as

UserAppearance.thisScreenName.title.configure(label: titleLabel)

Which may set all the property of your UI element...

But if you really, really badly want to have this you can still use something like strings as colors or pretty much any primitive...

You can create extensions like

extension UIView {

var backgroundColorString: String? {
set {
self.backgroundColor = UIColor(hexString: newValue)
}
get {
return self.backgroundColor.toHexString()
}
}

}

Then you obviously use this property to set the color directly from enumeration. But I discourage you to do this.

Swift extension and enum for color schemes

Don't use an enum then. If you don't want to enumerate on the values in a switch statement, there is no need for an enum. Use a struct with constant attributes.

struct Color {
static let border = UIColor(red:0.92, green:0.93, blue:0.94, alpha:1.00)
static let waterMelon = UIColor(red:0.97, green:0.38, blue:0.45, alpha:1.00)
// and so on ....
}

If you want to extend UIColor to have access to all the other colors of UIColor as well, you can extend UIColor like this:

extension UIColor {
static var border: UIColor {
return UIColor(red:0.92, green:0.93, blue:0.94, alpha:1.00)
}

static var waterMelon: UIColor {
return UIColor(red:0.97, green:0.38, blue:0.45, alpha:1.00)
}
}

Swift - Associated value or extension for an Enum

Unfortunately you cannot define static properties based on enum cases, but you can use computed properties and switch to return values for each case:

enum Icon {
case plane
case arrow
case logo
case flag

var image: UIImage {
switch self {
case .plane: return UIImage(named: "plane.png")!
case .arrow: return UIImage(named: "arrow.png")!
case .logo: return UIImage(named: "logo.png")!
case .flag: return UIImage(named: "flag.png")!
}
}

var color: UIColor {
switch self {
case .plane: return UIColor.greenColor()
case .arrow: return UIColor.greenColor()
case .logo: return UIColor.greenColor()
case .flag: return UIColor.greenColor()
}
}
}

// usage
Icon.plane.color

enum colors with dynamic alpha value

Welcome to the wild and wacky world of Swift case patterns. Change

case .yesColorWith(alpha: CGFloat) :

to

case .yesColorWith(let alpha) :

Thus:

enum Colors {
case text
case yesColorWith(alpha: CGFloat)
var color: UIColor {
switch self {
case .text:
return UIColorFromHEX(0xd1d1d1, alpha: 1.0)
case .yesColorWith(let alpha): // <-*
return UIColorFromHEX(0x89A225, alpha: alpha)
}
}
}

How to best create Uno card and deck with nested enum

Since Swift 4.2 you can use CaseIterable to get an array of all enum cases.

Simply change your enums to conform to the protocol:

enum color: String, CaseIterable {
// ...
}

enum faceValue: String, CaseIterable {
// ...
}

And perform a double for loop:

for color in color.allCases {
for faceValue in faceValue.allCases {
Deck.append(Card(color: color, faceVal: faceValue))
}
}

Also; structs, enums and classes should have a name that starts with a capital letter, so that would be Color, FaceValue and Card; whereas properties and variables should start with a lowercase letter, so that would be deck. That way you can see if a name is a class name or a variable name easily.



Related Topics



Leave a reply



Submit