Herakleis
Herakleis

Reputation: 533

Swifty way to get value associated with another in struct

I have a CustomColors struct which contains static lets that define primary and secondary colors for my app.

struct CustomColors {

    static let orangePrimary = UIColor(r: 255, g: 110, b: 64, a: 1)
    static let orangeSecondary = UIColor(r: 230, g: 74, b: 25, a: 1)

    static let bluePrimary = UIColor(r: 24, g: 255, b: 255, a: 1)
    static let blueSecondary = UIColor(r: 18, g: 191, b: 191, a: 1)

    static let yellowPrimary = UIColor(r: 255, g: 255, b: 0, a: 1)
    static let yellowSecondary = UIColor(r: 255, g: 193, b: 7, a: 1)
}

Because secondary colors are completely dependent from the primary ones, I am looking for a way to build a data structure (in the swiftiest way) that would allow me to call for example: CustomColors.bluePrimary.secondary to get the blueSecondary color.

I feel I am missing something pretty basic here as I cannot seem to see how I could do this in the most simple way.

Thanks in advance for your help !

Upvotes: 1

Views: 102

Answers (4)

Alexander Zakatnov
Alexander Zakatnov

Reputation: 1656

Try this way:

struct CustomColors {
    public class Color: UIColor {
        private var _secondary:UIColor?

        var secondary:UIColor? {
            get {
                return _secondary
            }
        }

        func setSecondary(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> Color {
            _secondary = UIColor(red: red, green: green, blue: blue, alpha: alpha)
            return self
        }

    }

    static let orangeColor = Color(red: 255, green: 110, blue: 64, alpha: 1).setSecondary(red: 230, green: 74, blue: 25, alpha: 1)

    static let blueColor = Color(red: 24, green: 255, blue: 255, alpha: 1).setSecondary(red: 18, green: 255, blue: 255, alpha: 1)

    static let yellowColor = Color(red: 255, green: 255, blue: 0, alpha: 1).setSecondary(red: 255, green: 193, blue: 7, alpha: 1)

}

CustomColors.orangeColor.secondary

It's more flexible way to implement what you want, I guess :)

Upvotes: 0

Paulw11
Paulw11

Reputation: 114856

Using discrete properties for the colours is not particularly scalable; you are dealing with with specific strings in your code, which are difficult to resolve at runtime.

I would suggest that you expand your structs to include a colour pair struct and enumeration to access the appropriate colour pair. Since an enumeration doesn't conform to hashable you can't use it as a dictionary key directly, but we can use a string raw value to get around that.

Something like:

struct CustomColors {

    struct Colors {
        let primary: UIColor
        let secondary: UIColor
    }

    enum Theme:String {
        case orange 
        case blue 
        case yellow
    }

    private let colors: [String:Colors] = [
        Theme.orange.rawValue: Colors(primary: UIColor(r: 255, g: 110, b: 64, a: 1),secondary: UIColor(r: 230, g: 74, b: 25, a: 1)),
        Theme.blue.rawValue: Colors(primary:UIColor(r: 24, g: 255, b: 255, a: 1), secondary:UIColor(r: 24, g: 255, b: 255, a: 1)),
        Theme.yellow.rawValue: Colors(primary:  UIColor(r: 255, g: 255, b: 0, a: 1), secondary: UIColor(r: 255, g: 193, b: 7, a: 1))

    ]

    func colorFor(theme: Theme) -> Colors {
        return colors[theme.rawValue]!
    }

}

Now you can, for example, track the currently active theme and use a variable to access the colours. Once you have the Colors struct, simply access the primary and secondary properties

let cc = CustomColors()
let activeTheme: CustomColors.Theme = .blue
print(cc.colorFor(theme: activeTheme).primary)

You can also use the raw value to easily identify and create a Theme

print(activeTheme)
if let someOtherTheme = CustomColors.Theme(rawValue: "yellow") {
    print(someOtherTheme)
}

Upvotes: 1

ZhihaoZhang
ZhihaoZhang

Reputation: 89

extension UIColor {
    open class var orangePrimary: UIColor {
        return UIColor.orange
    }
}

you can used UIcolor.orangePrimary

Upvotes: 0

Subramanian P
Subramanian P

Reputation: 4375

Create another struct for your colours and create your own types. And RGB values are float. Values should be divided by 255.0

 struct CustomColors {

    struct Blue {
        static let primary = UIColor(colorLiteralRed: 24.0/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0)
        static let secondary = UIColor(colorLiteralRed: 18.0/255.0, green: 191.0/255.0, blue: 191/255.0, alpha: 1.0)
    }

    struct Orange {
        static let primary = UIColor(colorLiteralRed: 255.0/255.0, green: 110.0/255.0, blue: 64/255.0, alpha: 1.0)
        static let secondary = UIColor(colorLiteralRed: 230.0/255.0, green: 74.0/255.0, blue: 25/255.0, alpha: 1.0)
    }

    struct Yellow {
        static let primary = UIColor(colorLiteralRed: 255.0/255.0, green: 255.0/255.0, blue: 0.0, alpha: 1.0)
        static let secondary = UIColor(colorLiteralRed: 255.0/255.0, green: 193.0/255.0, blue: 7/255.0, alpha: 1.0)
    }

}

Now you can access like CustomColors.Blue.primary

let blueColor = CustomColors.Blue.primary

Upvotes: 1

Related Questions