Первый шаг к созданию дизайн-системы
Мы используем различные и сложные архитектуры для создания приложений, которые легко поддерживать и расширять. Применение шаблонов проектирования, чтобы сделать наш код лучше. Наша цель как мобильных разработчиков — создавать приложения, которые не только красивы, когда они работают на пользовательских устройствах, но и красивы внутри, имеют читаемый и простой для понимания код.
Чистый код не должен содержать жестко запрограммированных значений. Иногда мы можем видеть такой код:
view.backgroundColor = #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1) label.text = "Some hardcoded text" imageView.image = UIImage(named: "SomeHardcodedImageName") label.font = UIFont.systemFont(ofSize: 16, weight: .regular)
С одной стороны, в этом нет абсолютно ничего плохого. Но представьте, что основной цвет вашего приложения изменился. А теперь нужно пройтись по всем файлам и везде заменить. Или вы решили локализовать свое приложение, теперь вам нужно найти все жестко запрограммированные строки в вашем коде и заменить их локализованными строками.
Это займет приличное количество времени и, скорее всего, вы пропустите какие-то места, поэтому строки не будут локализованы, или где-то у вас будут старые цвета. Это не сделает ваших пользователей счастливыми, а вы хотите, чтобы они были счастливы. Итак, позвольте мне показать, как управлять всеми вашими активами и ресурсами, чтобы избежать таких ситуаций.
Цвета
Начнем с цветов. Это отличная идея — хранить все цвета в одном месте. И мы собираемся сохранить все цвета внутри структуры. Создайте новый файл и создайте структуру с именем Colors внутри этого файла. Внутри этой структуры создайте константы static для всех цветов, которые у вас есть. Так:
struct Colors {
static let primary: UIColor = #colorLiteral(red: 0.9098039269, green: 0.4784313738, blue: 0.6431372762, alpha: 1)
static let secondary: UIColor = #colorLiteral(red: 0.8549019694, green: 0.250980407, blue: 0.4784313738, alpha: 1)
static let textPrimary: UIColor = #colorLiteral(red: 0.08120265152, green: 0.08120265152, blue: 0.08120265152, alpha: 1)
static let textSecondary: UIColor = #colorLiteral(red: 0.2549019754, green: 0.2745098174, blue: 0.3019607961, alpha: 1)
static let background: UIColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
// more colors...
}
И теперь, если вам нужен основной цвет, вы можете получить к нему доступ, используя всего два слова. Это помогает избавиться от жестко заданных цветов в вашем коде, но этот подход может работать только для небольших приложений с 2–3 экранами. Если вы создаете большое приложение с несколькими экранами и представлениями, вам нужно лучше управлять цветами.
Чтобы улучшить структуру Colors, нам нужно создать внутри нее вложенные структуры для каждого экрана, который есть в нашем приложении, и одну структуру для всех цветов, которые есть в нашей цветовой палитре. Допустим, у нас есть следующая цветовая палитра:

Во-первых, нам нужно создать вложенную структуру со всеми цветами из нашей палитры. Вы можете назвать его Global.
struct Colors {
private struct Global {
static let primary100 = #colorLiteral(red: 0.9568627451, green: 0.9215686275, blue: 1, alpha: 1)
static let primary200 = #colorLiteral(red: 0.9137254902, green: 0.8431372549, blue: 0.9960784314, alpha: 1)
// Other primary color shades
static let primary900 = #colorLiteral(red: 0.2588235294, green: 0.1882352941, blue: 0.4901960784, alpha: 1)
static let gray100 = #colorLiteral(red: 0.9490196078, green: 0.9568627451, blue: 0.968627451, alpha: 1)
static let gray200 = #colorLiteral(red: 0.8941176471, green: 0.9058823529, blue: 0.9254901961, alpha: 1)
// Other gray color shades
static let gray900 = #colorLiteral(red: 0.06274509804, green: 0.09411764706, blue: 0.1568627451, alpha: 1)
// Other colors and their shades
}
}
Важно сделать его private, чтобы он был доступен только внутри структуры Colors. Мы не собираемся использовать Global вне структуры Colors. Как я уже говорил ранее, нам нужны вложенные структуры для каждого экрана, который у нас есть. Итак, теперь мы создадим их и будем использовать цвета из Global внутри этих новых структур. Внутри этих структур нам нужно создать статические константы для каждого компонента пользовательского интерфейса, которому нужен цвет.
struct Colors {
private struct Global {
static let primary100 = #colorLiteral(red: 0.9568627451, green: 0.9215686275, blue: 1, alpha: 1)
static let primary200 = #colorLiteral(red: 0.9137254902, green: 0.8431372549, blue: 0.9960784314, alpha: 1)
// Other primary color shades
static let primary900 = #colorLiteral(red: 0.2588235294, green: 0.1882352941, blue: 0.4901960784, alpha: 1)
static let gray100 = #colorLiteral(red: 0.9490196078, green: 0.9568627451, blue: 0.968627451, alpha: 1)
static let gray200 = #colorLiteral(red: 0.8941176471, green: 0.9058823529, blue: 0.9254901961, alpha: 1)
// Other gray color shades
static let gray900 = #colorLiteral(red: 0.06274509804, green: 0.09411764706, blue: 0.1568627451, alpha: 1)
// Other colors and their shades
}
struct SignUp {
static let title: UIColor = Global.gray900
static let subtitle: UIColor = Global.gray200
static let button: UIColor = Global.primary900
// Colors for other components
}
struct Settings {
static let title: UIColor = Global.gray900
static let subtitle: UIColor = Global.gray200
static let button: UIColor = Global.primary900
// Colors for other components
}
// Structs for other screens
}
Теперь, когда вам нужно установить метку заголовка textColor на экране регистрации, вы должны сделать это следующим образом:
titleLabel.textColor = Colors.SignUp.title
Такой подход помогает хранить все цвета в одном месте, а также позволяет обновлять цвет для определенного вида за несколько секунд. Для этого нужно всего лишь найти нужный цвет внутри структуры Colors и изменить его значение.
Активы для цветов
Если вы хотите, чтобы ваш код был более гибким, я предлагаю вам использовать Assets для создания цветов. Почему? Однажды вы, возможно, захотите добавить поддержку темного режима для своего приложения. И в этом случае вам придется переместить все свои цвета из структуры Global в структуру Assets. Кроме того, код для цвета, созданный с помощью Assets, выглядит намного лучше, чем код, созданный с помощью #colorLiteral.
Создайте новый Asset Catalog и назовите его Colors. Внутри этого нового каталога создайте наборы цветов для каждого цвета в структуре Global. Вы также можете сгруппировать все оттенки каждого цвета в папки.

Теперь мы можем избавиться от цветовых литералов внутри структуры Global и заменить их цветами из активов. Чтобы получить цвет, который у вас есть внутри Assets Catalog, вам нужно использовать специальный инициализатор UIColor(named: ) для активов. Эта инициализация необязательна. Вы можете использовать дополнительные цвета, это не проблема, так как все цветовые свойства представлений являются необязательными. Но вы также можете принудительно развернуть цвета из файла Assets. В этом нет ничего плохого, потому что вы можете быть уверены, что принудительное развертывание не подведет.
private struct Global {
static let primary100 = UIColor(named: "primary100")!
static let primary200 = UIColor(named: "primary200")!
// Other primary color shades
static let primary900 = UIColor(named: "primary900")!
static let gray100 = UIColor(named: "gray100")!
static let gray200 = UIColor(named: "gray200")!
// Other gray color shades
static let gray900 = UIColor(named: "gray900")!
// Other colors and their shades
}
Шрифты
Тот же подход можно применить и к шрифтам. Не кодируйте их жестко внутри своих представлений, создайте структуру Fonts и переместите в нее все. Для Fonts вам также нужно создать структуру Global и поместить внутрь все стили текста. Затем вам нужно начать создавать вложенные структуры для всех ваших экранов и создавать внутри статические константы.
struct Fonts {
private struct Global {
static let heading1: UIFont = .systemFont(ofSize: 24, weight: .semibold)
static let heading2: UIFont = .systemFont(ofSize: 22, weight: .semibold)
static let heading3: UIFont = .systemFont(ofSize: 20, weight: .semibold)
static let bodyText1: UIFont = .systemFont(ofSize: 18, weight: .regular)
static let bodyText2: UIFont = .systemFont(ofSize: 16, weight: .regular)
static let bodyText3: UIFont = .systemFont(ofSize: 14, weight: .regular)
}
struct SignUp {
static let title = Global.heading2
static let subtitle = Global.bodyText2
}
struct Settings {
static let title = Global.heading2
static let cellText = Global.bodyText2
}
// Structs for other screens
}
Струны
Это работает почти так же для строк, за исключением одной маленькой вещи. Со строками вам не нужна структура Global. Просто создайте вложенные структуры для своих экранов и поместите свой контент в статические константы.
struct Strings {
struct SignUp {
static let title = "Sign up!"
static let subtitle = "Create a strong password!"
}
struct Settings {
static let title = "Settings"
static let darkMode = "Enable dark mode?"
static let battery = "Battery Life"
static let localisation = "Do you want to change language?"
}
// Structs for other screens
}
Изображения и значки
С изображениями я использую немного другой подход. Я не создаю вложенные структуры. Просто создайте структуру, назовите ее Images или Icons и поместите все свои изображения в статические константы.
struct Icons {
static let backArrow: UIImage = UIImage(named: "backArrow")!
static let home: UIImage = UIImage(named: "homeIcon")!
static let settings: UIImage = UIImage(named: "settingsGear")!
static let rightChevron: UIImage = UIImage(named: "rightChevron")!
}
Заключение
Если вы все еще жестко кодируете все свои цвета, шрифты, строки и изображения, я настоятельно рекомендую вам попробовать подход из этой статьи. Это сделает ваш код чище, а также ускорит разработку.
Надеюсь, вам понравилась эта статья и вы нашли ее полезной. Не стесняйтесь делиться своими мыслями в разделе комментариев.
Check out my other articles about iOS Development https://medium.com/@artem.khalilyaev
Повышение уровня кодирования
Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:
- 👏 Хлопайте за историю и подписывайтесь на автора 👉
- 📰 Смотрите больше контента в публикации Level Up Coding
- 💰 Бесплатный курс собеседования по программированию ⇒ Просмотреть курс
- 🔔 Подписывайтесь на нас: Twitter | ЛинкедИн | "Новостная рассылка"
🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу