Невозможно программно изменить набор цветов в раскадровке как цвет из каталога xcassets

Когда я устанавливаю цвет некоторого свойства в раскадровке (например, textColor из моего UILabel) как цвет, созданный как новый набор цветов в каталоге xcassets

тогда я не могу программно изменить этот цвет с первой попытки:

label.textColor = UIColor(named: "HighlightedGreen")

... обратите внимание, что я вызываю его из метода источника данных cellForItemAt,

Я могу решить эту проблему, установив этот цвет в раскадровке для любого другого цвета, выбранного из палитры цветов, но я хочу знать, почему это происходит.

Итак, почему это происходит?

1 ответ

Решение

Когда UIViewsubClass лайк UITableViewCell загружается из Storyboard/Xib, он применяет атрибуты, указанные в Attribute Inspector для всех subViews, У нас есть следующие методы обратного вызова, чтобы знать, когда представление загружается из Storyboard/Xib,

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()        
}

override func awakeFromNib() {
    super.awakeFromNib()
}

Эти методы могут быть хорошими кандидатами для добавления / удаления подвид, но они не должны обновлять подвид size или некоторые из attribute inspector связанные свойства. Рекомендуемый метод для обновления подвидов, когда суперпредставление завершает загрузку и применение всех attribute inspector свойства и звонки layoutSubviews, Итак, вы должны применить любое косметическое изменение к подпредставлению. например,

override func layoutSubviews() {
    super.layoutSubviews()

    label.textColor = UIColor(named: "HighlightedGreen")
}

Для UITableViewCellлюбой объект, реализующий UITableViewDataSource также гарантирует delegate Метод применения любых косметических изменений перед отображением ячейки, как показано ниже, так что это еще один хороший вариант для изменения цвета.

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    (cell as! MyListTableViewCell).label.textColor = UIColor(named: "HighlightedGreen")
}

Настоящий ответ заключается в том, что это ближе к ошибке. В iOS 13 нет проблем с программным замещением цветового актива, установленного в IB, любым другим цветом.

Я взял несколько журналов из сеанса отладки iOS 12, в котором я пытался, что делает OP:

Ячейка 1

В awakeFromNib: UIExtendedSRGBColorSpace 0,235 0,235 0,263 0,6
Установка цвета фона на: UIExtendedSRGBColorSpace 0,235 0,235 0,263 0,6
В layoutSubviews: kCGColorSpaceModelRGB 0,235 0,235 0,263 0,6

Ячейка 2

В awakeFromNib: UIExtendedSRGBColorSpace 0,235 0,235 0,263 0,6
Настройка цвет фона: kCGColorSpaceModelRGB 0.490196 0,760784 0,262745 1
В layoutSubviews: kCGColorSpaceModelRGB 0,235 0,235 0,263 0,6

В iOS 13 журналы (и результаты) разные:

Ячейка 1

В awakeFromNib: UIDynamicCatalogColor: 0x600003e83600; name = My Background Color
Установка цвета фона на: UIExtendedSRGBColorSpace 0,235 0,235 0,263 0,6
В layoutSubviews: UIExtendedSRGBColorSpace 0,235 0,235 0,263 0,6

Ячейка 2

В awakeFromNib: UIDynamicCatalogColor: 0x600003e99290; name = My Background Color
Установка цвета фона на: UIDynamicCatalogColor: 0x600003e99020; name = Зеленая кнопка в
layoutSubviews: UIDynamicCatalogColor: 0x600003e99350; name = Зеленая кнопка

Кажется, что существует проблема синхронизации, когда iOS 12 переводит именованный цвет в цветовое пространство, которое он использует, что происходит во время layoutSubviews()поэтому попытки изменить цвет до этого момента тщетны. Однако iOS 13, похоже, изначально использует UIDynamicCatalogColor без перевода, поэтому нет проблемы с синхронизацией.

Цветовые ассеты кажутся немного запоздалыми для Xcode в целом. Удачи в переименовании их после того, как они были использованы в вашем приложении, использовании их с #colorLiteral или изменении их для разных коллекций признаков. К сожалению, лучшее решение на данный момент - вообще не использовать их в IB.

Другие вопросы по тегам