简体   繁体   中英

Swift Enum design issues : 1. multiple cases having same value, 2. returning custom enum value

I'm maintaining an enum with the majority of font sizes used in my app like so -

enum FontSize : CGFloat
{
    case HeaderSize = 20
    case TitleSize = 18
    case PrimaryButtonTextSize = 22
}

I have written this convenience method in a UIFont extension that I wish to use across the app like -

static func fontWithSize(size:FontSize) -> UIFont?
{
  return font = UIFont(name:"System" , size: size.rawValue)
}

USAGE -

headerLabel.font = UIFont.fontWithSize(.HeaderSize)

Now I'm facing 2 issues with this design -

#1

Since I'm identifying font sizes by where they are used in UI I would most likely add more cases in the future as -

enum FontSize : CGFloat
{
    case HeaderSize = 20
    case TitleSize = 18
    case PrimaryButtonTextSize = 22

    // Newly added 
    case SpecialButtonTextSize = 20
    case SpecialTitleTextSize = 10
}

The problem is that swift enum will not allow me to add multiple cases with same value. Of course I could just remove SecondaryButtonTextSize or SpecialTitleTextSize and always use .HeaderSize -

specialButton.font = UIFont.fontWithSize(.HeaderSize)
specialTitle.font = UIFont.fontWithSize(.HeaderSize)

But this would mean that if I decide to change HeaderSize later I'd be missing out on my special button and special title cases. Also call me crazy but I'd be happier if I could use those enums like that.

#2

Now of course this enum will not be an exhaustive list of all font sizes my app uses. There'll be those one-off cases where I'll have to pass in a size value for a one time use only.

One solution is to just have another method like -

static func fontWithSize(size:CGFloat) -> UIFont?
{
  return font = UIFont(name:"System" , size: size)
}

But It'd be awesome if somehow I could continue using my enum and make it return a custom value. maybe it'd look something like

enum FontSize : CGFloat
{
    case HeaderSize = 20
    case TitleSize = 18
    case PrimaryButtonTextSize = 22
    case CustomSize(CGFloat) -> CGFloat    // lolwut?
}

I know this might be a trivial thing to worry about, but it'd be great to have some design solution for this issue. Maybe enums aren't the solution at all! Any pointers will help!

Your enum have init(rawValue: CGFloat) initializer. If you'll use the same rawValue for different cases, it won't be able to decide which case produce from this value. So it's no surprise compiler doesn't allow to do that.

Solution to your problem is simple: get rid of case s and use static var s instead:

enum FontSize {
    static var HeaderSize: CGFloat = 20.0
    static var SpecialButtonTextSize: CGFloat = 20.0
    static var SpecialTitleTextSize: CGFloat = 10.0
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM