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