Search code examples
swiftwrapperenumeration

Accessing a non raw type enumerations case values?


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?


Solution

  • 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.