Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Enumerations and Optionals in Swift Introduction to Enumerations Enum Methods

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

enum code typed exactly as written in video but still getting a slew of errors

Here's my code. If it helps, I'm running the most recent version of Xcode, which was updated after the new iOs release.

import UIKit

enum ColorComponent {
    case rgb(red: Float, green: Float, blue: Float, alpha: Float)
    case hsb(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)

    func color() -> UIColor {
        switch self {
        case .rgb(let red, let green, let blue, let alpha):
            return UIColor(colorLiteralRed: red/255.0, green: green/255.0, blue: blue 255.0, alpha: alpha)
        case .hsb(let hue, let saturation, let brightness, let alpha):
            return UIColor(hue: hue/360.0, saturation: saturation/100.0 , brightness: brightness/100, alpha: alpha)
        }
    }
}

ColorComponent.rgb(red: 61.0, green: 120.0, blue: 198.0, alpha: 1.0).color()

Yet I'm getting these errors and Xcode seems to continuously try to run it but never finishes.

Error 1 (pretty sure I have the curly brace in there already... so no clue what's going on):

Playground execution failed:

error: EnumerationsOptionals.playground:57:20: error: expected '{' after 'switch' subject expression
        switch self
                   ^

Error 2 (I can't seem to find where I'm missing a ','):

Expected ',' separator

Error 3 (no clue what this means):

Cannot invoke initializer for type 'UIColor' with an argument list of type '(colorLiteralRed: Float, green: Float, blue: Float, Double, alpha: Float)'

Error 4 (no clue what this means, either):

Overloads for 'UIColor' exist with these partially matching parameter lists: (white: CGFloat, alpha: CGFloat), (hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat), (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat), (displayP3Red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat), (cgColor: CGColor), (CGColor: CGColor), (patternImage: UIImage), (ciColor: CIColor), (CIColor: CIColor), (), (coder: NSCoder), (_colorLiteralRed: Float, green: Float, blue: Float, alpha: Float), (named: String), (named: String, in: Bundle?, compatibleWith: UITraitCollection?), (named: String, inBundle: Bundle?, compatibleWithTraitCollection: UITraitCollection?)
buttons.swift
// Example of UIBarButtonItem instance
// let someButton = UIBarButtonItem(title: "A Title", style: .plain, target: nil, action: nil)

enum BarButton {
    case done(title: String)
    case edit(title: String)
}

3 Answers

Jhoan Arango
Jhoan Arango
14,575 Points

Hello,

So there are just a few errors in your code, one you are missing the division on one of your parameters in the UIColor init. The other one is that UIColor(colorLiteralRed:) is not the initializer you should be using in this case. And the other is you should use CGFloat in your Associated value type.

Here is the code :

enum ColorComponent {
    case rgb(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) // We now have CGFloat
    case hsb(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)

    func color() -> UIColor {
        switch self {
        case .rgb(let red, let green, let blue, let alpha):
            return UIColor(displayP3Red: red/255, green: green/255, blue: blue/255, alpha: alpha) // Using Correct Init
        case .hsb(let hue, let saturation, let brightness, let alpha):
            return UIColor(hue: hue/360.0, saturation: saturation/100.0 , brightness: brightness/100, alpha: alpha)
        }
    }
}

let color = ColorComponent.rgb(red: 10, green: 10, blue: 10, alpha: 1)

Good luck

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

Thank you for your response! That was helpful. Apart from the missing division sign, I got tripped up because this is how the code was written in Pasan's video and worked for him (maybe it's because he's using an older version of Swift?). I can let Treehouse know, though.

Some of this stuff is still a little confusing to me, as I'm not quite sure why to use displayP3Red over colorLiteralRed, but I'm sure that will come with time and practice. But could you explain why we make everything CGFloat as the associated value for both cases?

Jhoan Arango
Jhoan Arango
14,575 Points

Hello Michael,

Yeah, colorLiteral was deprecated in Swift 4, so you won't be able to use that anymore. The initializer displayP3Red is technically the same.

Now, on your next question the reason why we are using CGFloat, is because that's what the initializer for the UIColor() takes in.

/// Initializer for UIColor
UIColor(displayP3Red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)

When you create an enum with associated values, you give it the type you want the associated value to be. And whenever you are extracting the value with a switch, that value will be of the type you provided.

In this case we are saying:

enum ColorComponent {

   // I want the associated values for this case to be of type CGFloat
    case rgb(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)

   // Then..

    func color() -> UIColor {
        switch self {
        case .rgb(let red, let green, let blue, let alpha): // We then extract those values using a constant.
            return UIColor(displayP3Red: red/255, green: green/255, blue: blue/255, alpha: alpha) // THEN we pass those values to this initializer which takes in  CGFloats.
        }
    }
}

So in short... The initializer takes in CGFloats so we made the associated value to be of that type, if the init took Doubles, then we would have made the associated values of type Doubles.

I hope this clears your mind a bit.. if you need more help let me know.

Good luck

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

Thank you for your help. The logic makes sense, but I'm still trying to wrap my head around some of the new code, like CGFloat and switch self. The latter, I think is similar to initializers for Classes and Structs, but it's just a new format. So working to ensure it sinks in. Think the best course of action is to just keep practicing/working through the course unless you have other pointers.