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 Swift 2.0 Enumerations and Optionals Introduction to Enumerations Enum Methods

Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,735 Points

How do I access the String property of my enum? (And other questions)

import Foundation

enum UIBarButtonStyle {
    case Done
    case Plain
    case Bordered
}

class UIBarButtonItem {

    var title: String?
    let style: UIBarButtonStyle
    var target: AnyObject?
    var action: Selector

    init(title: String?, style: UIBarButtonStyle, target: AnyObject?, action: Selector) {
        self.title = title
        self.style = style
        self.target = target
        self.action = action
    }
}

enum Button {
    case Done(String)
    case Edit(String)

    func toUIBarButtonItem() -> UIBarButtonItem {
        var style: UIBarButtonStyle

        switch self {
            case .Done: style = UIBarButtonStyle.Done
            case .Edit: style = UIBarButtonStyle.Plain
        }

         // This is where I'm confused - to pass in the String for the title property of the new UIBarButtonItem I put in 'self'
        return UIBarButtonItem(title: self, style: style, target: nil, action: nil)
    }
}

let done = Button.Done("Done")
let doneButton = done.toUIBarButtonItem()

I just put "self" but I don't know how to access this string properly.

Also, what is the difference between a rawValue and an associated value?

Another question - they're asking us to pass in nil for the action property, but the type - Selector - isn't an optional. Is that because it is NilLiteralConvertible? Why are the other ones optionals?

1 Answer

Michael Reining
Michael Reining
10,101 Points

Hi Brendan,

A very basic enum has no string property. Such as the example below.

enum FlightStatus  {
    case Ontime
    case Delayed
    case Cancelled
}

let myFlightStatus = FlightStatus.Ontime

However, you can create enums that have an associated value of type Int or type String.
Here is an example.

enum Title: String {
    case CEO = "Chief Executive Officer"
    case COO = "Chief Operating Officer"
}

let myTitle = Title.CEO.rawValue
print(myTitle)

// In the example above, you access the string property via the rawValue since the rawValue is now of type String

An enum with associated values looks like the example below.

enum Button {
    case Done(String)
    case Edit(String)
}

let myDoneButton = Button.Done("I am Done!")

I hope that helps answer your question. There are a lot more examples here:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html

Next you have to initialize a new UIBarButtonItem. This is done like this.

enum UIBarButtonStyle {
    case Done
    case Plain
    case Bordered
}

class UIBarButtonItem {

    var title: String?
    let style: UIBarButtonStyle
    var target: AnyObject?
    var action: Selector

    init(title: String?, style: UIBarButtonStyle, target: AnyObject?, action: Selector) {
        self.title = title
        self.style = style
        self.target = target
        self.action = action
    }
}

let myButtonItem = UIBarButtonItem(title: "Button Item Name", style: UIBarButtonStyle.Plain, target: nil, action: nil)

// Above you set the title to whatever string you like
// You also have to set the UIBarButtonStyle to one of the accepted values such as plain

Now if you put everything together and you end up with this.

enum Button {
    case Done(String)
    case Edit(String)

    func toUIBarButtonItem() -> UIBarButtonItem {
        switch self {
        case .Done: return UIBarButtonItem(title: "Done", style: UIBarButtonStyle.Done, target: nil, action: nil)
        case .Edit: return UIBarButtonItem(title: "edit", style: UIBarButtonStyle.Plain, target: nil, action: nil)
        }
    }
}

let done = Button.Done("Done")
let doneButton = done.toUIBarButtonItem()

I hope that helps to clear things up.

Mike

PS: Thanks to the awesome resources on Team Treehouse, I just launched my first app. :-)

Code! Learn how to program with Swift

Brendan Whiting
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Brendan Whiting
Front End Web Development Techdegree Graduate 84,735 Points

It seems like you're just hard coding in the title "Done" inside the toUIBarButtonItem function. Wouldn't it be better to access the "Done" string that we put into the constant done when we created it? How do we access that property?

enum Button {
    case Done(String) // How do we access this string property?
    case Edit(String)

    func toUIBarButtonItem() -> UIBarButtonItem {
        switch self {
        case .Done: return UIBarButtonItem(title: "Done", style: UIBarButtonStyle.Done, target: nil, action: nil)  
 // This 'Done' seems like we're hard coding it in

        case .Edit: return UIBarButtonItem(title: "edit", style: UIBarButtonStyle.Plain, target: nil, action: nil)
        }
    }
}

let done = Button.Done('Done') // How do we access this 'Done' ?
let doneButton = done.toUIBarButtonItem()