The way to control color schemes "Swift" "iOS" -application
Even for a beginner developer himself (rather, for whom this essay is designed), I hope it’s no secret that no so-called code should be present in the code. "Hardcoded" -values and all sorts of other "magic numbers" there . Why - it’s also, I hope, understandable, and if not, then there are dozens, if even hundreds of articles on this topic on the Web, as well as a classic work . “Android Studio” (probably not in all cases, but still) even likes to generate “warnings” on this topic and offer to make lines, etc. to resource files . “Xcode” (yet?) Doesn’t indulge us with such tips, and the developer has to keep himself in check or, say, get his hands on the hands of colleagues after"Code review" .
All this applies to the colors used in the application.
For starters, I want to give some more or less standard recommendations.
First, the colors of all elements are best set immediately in the code, and not in the “Storyboard” / “Interface Builder” . Unless, of course, this is an application with one screen with three elements and in one color scheme. But even in this case, you never know for sure how the situation will change in the future.
Secondly, all the colors should be determined by constants taken out in a separate file. Or in a separate group next to the corresponding "view" code.
Thirdly, colors should be divided into categories. Those. operate not with “the color of the second button on the first screen”, but with something like “the background color of the main type of buttons”.
If a designer (or from his own sense of taste) receives a signal to change the color of any element, you don’t have to look for it for a long time - just change it in several places (forgetting one of them and clutching your head after sending the application to iTunes Connect) ) - two.
Thus, we will have, for example, a file
(
Using color will look like this:
I suggest going further and writing a model that will represent the different colors used in the application:
For ease of creation, you can even write
In this case, the constants will look like this:
In the code, the color will be set this way:
And finally, why such additional difficulties might be needed - this ...
Suppose we want our application to have two color schemes: dark and light. To store a list of color schemes, define
In this case, I think it will not be shameful to create a type for representing the color scheme model as a “singleton” :
I would even define it inside
Itself
Color constants will now look like this:
(
And the use of all this stuff will look the same:
To change the color of some element, only changes to the corresponding constant are still enough. And to add another color scheme, you need to add
The latter, of course, can still be improved. For example, if the number of circuits grows, it is probably more convenient to replace the bulky initializer with a "builder" .
Perhaps this time everything! Have a nice code!
All this applies to the colors used in the application.
Last updated February 16, 2019.
Color constants
For starters, I want to give some more or less standard recommendations.
First, the colors of all elements are best set immediately in the code, and not in the “Storyboard” / “Interface Builder” . Unless, of course, this is an application with one screen with three elements and in one color scheme. But even in this case, you never know for sure how the situation will change in the future.
Secondly, all the colors should be determined by constants taken out in a separate file. Or in a separate group next to the corresponding "view" code.
Thirdly, colors should be divided into categories. Those. operate not with “the color of the second button on the first screen”, but with something like “the background color of the main type of buttons”.
If a designer (or from his own sense of taste) receives a signal to change the color of any element, you don’t have to look for it for a long time - just change it in several places (forgetting one of them and clutching your head after sending the application to iTunes Connect) ) - two.
Thus, we will have, for example, a file
Colors.swift
with contents like:import UIKit
enumButtonAppearance{
staticlet backgroundColor = UIColor.white
staticlet borderColor = UIColor.gray
staticlet textColor = UIColor.black
}
(
enum
Without a single one case
, to be honest, my favorite type structure is to declare constants. With this use, it automatically deprives us of the opportunity to create instances of the type and generally use the type in any way other than the intended way.) Using color will look like this:
let someButton = UIButton()
someButton.backgroundColor = ButtonAppearance.backgroundColor
someButton.layer.borderColor = ButtonAppearance.borderColor.cgColor
Color model
I suggest going further and writing a model that will represent the different colors used in the application:
structSchemeColor{
privatelet color: UIColorfuncuiColor() -> UIColor {
return color
}
funccgColor() -> CGColor {
return color.cgColor
}
}
For ease of creation, you can even write
extension
for UIColor
:extensionUIColor{
funcschemeColor() -> SchemeColor {
returnSchemeColor(color: self)
}
}
In this case, the constants will look like this:
enumButtonAppearance{
staticlet backgroundColor = UIColor.white.schemeColor()
staticlet borderColor = UIColor.gray.schemeColor()
staticlet textColor = UIColor.black.schemeColor()
}
In the code, the color will be set this way:
let someButton = UIButton()
someButton.backgroundColor = ButtonAppearance.backgroundColor.uiColor()
someButton.layer.borderColor = ButtonAppearance.borderColor.cgColor()
And finally, why such additional difficulties might be needed - this ...
Color schemes
Suppose we want our application to have two color schemes: dark and light. To store a list of color schemes, define
enum
:enumColorSchemeOption{
case dark
case light
}
In this case, I think it will not be shameful to create a type for representing the color scheme model as a “singleton” :
structColorScheme{
staticlet shared = ColorScheme()
private (set) var schemeOption: ColorSchemeOptionprivateinit() {
/*
Здесь должен быть код, который определит цветовую схему и присвоит нужное значение option. Например, загрузив настройки из UserDefaults или взяв значение по умолчанию, если сохраненных настроек нет.
*/
}
}
I would even define it inside
SchemeColor
and make it private
. Itself
SchemeColor
needs to be modified so that it is aware of what color scheme the application uses and returns the desired color:structSchemeColor{
let dark: UIColorlet light: UIColorfuncuiColor() -> UIColor {
return colorWith(scheme: ColorScheme.shared.schemeOption)
}
funccgColor() -> CGColor {
return uiColor().cgColor
}
privatefunccolorWith(scheme: ColorSchemeOption) -> UIColor {
switch scheme {
case .dark: return dark
case .light: return light
}
}
// ColorScheme
}
Color constants will now look like this:
enumButtonAppearance{
staticlet backgroundColor = SchemeColor(dark: Dark.backgroundColor, light: Light.backgroundColor)
staticlet borderColor = SchemeColor(dark: Dark.borderColor, light: Light.borderColor)
staticlet textColor = SchemeColor(dark: Dark.textColor, light: Light.textColor)
privateenumLight{
staticlet backgroundColor = UIColor.white
staticlet borderColor = UIColor.gray
staticlet textColor = UIColor.black
}
privateenumDark{
staticlet backgroundColor = UIColor.lightGray
staticlet borderColor = UIColor.gray
staticlet textColor = UIColor.black
}
}
(
extension
for UIColor
, it seems, it is no longer needed.) And the use of all this stuff will look the same:
let someButton = UIButton()
someButton.backgroundColor = ButtonAppearance.backgroundColor.uiColor()
someButton.layer.borderColor = ButtonAppearance.borderColor.cgColor()
To change the color of some element, only changes to the corresponding constant are still enough. And to add another color scheme, you need to add
case
to the ColorSchemeOption
set of colors for this color scheme in color constants and update SchemeColor
. The latter, of course, can still be improved. For example, if the number of circuits grows, it is probably more convenient to replace the bulky initializer with a "builder" .
Perhaps this time everything! Have a nice code!