Search code examples
iosswiftenumsuicolor

Declaring an enum to change color used in app for different type of users


I'm developing an app which has two type of user (Admin, Normal User). Color of UITabBar and NavigationBar changes according to user type. How I declare colors;

struct Color{
struct NavigationBar{
    static let tintColor =  UIColor(red:0.01, green:0.54, blue:0.16, alpha:1.0)
    static let textColor = UIColor.white
}

How I call;

tabBarController.tabBar.barTintColor = Color.TabBar.tintColor

I can write an If statement in where I call "Color.TabBar" and choose right color but I'm wondering If I can do it with enum. Like below code;

struct Color{
struct NavigationBar{
    enum tintColor{
        case admin
        case user
        var color: UIColor{
            switch self {
            case .admin:
                return UIColor(red:0.01, green:0.54, blue:0.16, alpha:1.0)
            case .user:
                return UIColor(red:0.01, green:0.54, blue:0.16, alpha:1.0)
            default:
                return UIColor(red:0.01, green:0.54, blue:0.16, alpha:1.0)
            }
        }
    }
    //static let tintColor =  UIColor(red:0.01, green:0.54, blue:0.16, alpha:1.0)
    static let textColor = UIColor.white
}

I find below article but I think this does not related with my problem. So my question is that how can I write that kind of enum?

How can I make a Swift enum with UIColor value


Solution

  • I believe what you want is not possible. Enum may not be a class, only a generic type, a structure.

    But it is usually not what you want as when you will have many of these values you will have a mess anyway. For instance at some point you will have a button background color, border color and text color. Then waht do you expect your result to be like:

    button.backgroundColor = UIButton.backgroundColor
    button.layer.borderColor = UIButton.borderColor.cgColor
    button.label.textColor = UIButton.textColor
    

    And now having 3 enums for a single component... It is a solution but I think it is a bad one...

    I suggest you rather create a static class and have it like so:

    class UserApperance {
        static var userType: UserType = .admin
    
        static var navigationTintColor: UIColor {
            switch userType {
                case .admin: ...
                case .user: ...
            }
        }
    
    }
    

    So all you will do in the code is again

    tabBarController.tabBar.barTintColor = UserApperance.navigationTintColor
    

    And when you want to group them you can use nesting:

    class UserApperance {
        static var userType: UserType = .admin
    
        class NavigationBar {
            static var tintColor: UIColor {
                switch UserApperance.userType {
                    case .admin: ...
                    case .user: ...
                }
            }
        }
    
    
    }
    

    Where the result is now nicer:

    tabBarController.tabBar.barTintColor = UserApperance.NavigationBar.tintColor
    

    In my opinion this is the nicest way and with really hard situations like white-label applications you can really play around with nesting and do it per screen and even have code like:

    let appearance =  UserAppearance.thisScreenName
    titleLabel.textColor = appearance.title.textColor
    titleLabel.font = appearance.title.font
    

    Bot to mention you can generalize some things and even have usage as

    UserAppearance.thisScreenName.title.configure(label: titleLabel)
    

    Which may set all the property of your UI element...

    But if you really, really badly want to have this you can still use something like strings as colors or pretty much any primitive...

    You can create extensions like

    extension UIView {
    
        var backgroundColorString: String? {
            set {
                self.backgroundColor = UIColor(hexString: newValue)
            }
            get {
                return self.backgroundColor.toHexString()
            }
        }
    
    }
    

    Then you obviously use this property to set the color directly from enumeration. But I discourage you to do this.