-2

So I have an enumeration defined as the following:

enum CardPosition {
    case top(CGFloat) 
    case middle(CGFloat)
    case bottom(CGFloat) 
}

I have a variable of type CardPosition that is defined as:

@State private var position: CardPosition = CardPosition.bottom(UIScreen.main.bounds.height - 100)

How do I access the value of the CardPosition? In this case, I'm trying to access the UIScreen.main.bounds.height - 100 value from the enumeration. I tried accessing it with

self.position.rawValue 

but unfortunately this doesn't work. Anyone know how I can access the CGFloat value of position?

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
nickcoding
  • 305
  • 8
  • 35
  • 1
    `Swift Enum + Associated Values` These are the keywords you were missing. Read https://docs.swift.org/swift-book/LanguageGuide/Enumerations.html#ID148 for instance. – Larme Jul 09 '20 at 07:27
  • 1
    Does this answer your question? [Accessing an Enumeration association value in Swift](https://stackoverflow.com/questions/24263539/accessing-an-enumeration-association-value-in-swift) – Larme Jul 09 '20 at 08:17

3 Answers3

1

You need to use a switch here:

switch position {
case .top(let f):
    // use f
case .middle(let f):
    // use f
case .bottom(let f):
    // use f
}

If you want it as an expression, you can do something like:

// you can assign the below to a variable or whatever
// let value =
{ () -> CGFloat in
    switch position {
    case .top(let f):
        return f
    case .middle(let f):
        return f
    case .bottom(let f):
        return f
    }
}()

However, I think the best solution is to redesign your types. It seems like there will always be a CGFloat associated with every case of your enum. Why not use a struct composing a simple enum and a CGFloat?

enum RelativeCardPosition {
    case top
    case middle
    case bottom
}

struct CardPosition {
    let relativeCardPosition: RelativeCardPosition
    let offset: CGFloat
    
    static func top(_ offset: CGFloat) -> CardPosition {
        CardPosition(relativeCardPosition: .top, offset: offset)
    }
    
    static func middle(_ offset: CGFloat) -> CardPosition {
        CardPosition(relativeCardPosition: .middle, offset: offset)
    }
    
    static func bottom(_ offset: CGFloat) -> CardPosition {
        CardPosition(relativeCardPosition: .bottom, offset: offset)
    }
}

Then you can easily access the number via position.offset.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

You can create a Computed Property position inside the enum CardPosition and return the associated value with each case, i.e.

enum CardPosition {
    case top(CGFloat)
    case middle(CGFloat)
    case bottom(CGFloat)
    
    var position: CGFloat {
        switch self {
        case .top(let pos), .middle(let pos), .bottom(let pos):
            return pos
        }
    }
}
PGDev
  • 23,751
  • 6
  • 34
  • 88
  • I don't think it should have been downvoted. Maybe [Tim lost his keys](https://meta.stackexchange.com/a/215397/302707). Don't worry about it :) – Sweeper Jul 09 '20 at 08:31
1

To get the associated value for your .bottom variable you use if let case syntax

var position: CardPosition = CardPosition.bottom(UIScreen.main.bounds.height - 100.0)

if case let CardPosition.bottom(positionValue) = position {
    print(positionValue)
}

This will give you only a value for .bottom and not for any of the other enum cases.

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52