Сравнение двух UIColor DynamicProvider (iOS13) возвращает False

Xcode 11 / iOS 13

Когда я инициализирую 2 объекта UIColor с помощью UIColor(dynamicProvider:), я больше не могу использовать color1 == color2, поскольку (я думаю) он не может сравнивать закрытие.

Эта проблема также нарушает сравнение NSAttributedStrings при использовании цветов в атрибутах.

Пример

extension UIColor {

    // MARK: - Specify All Colors

    convenience init(light: UIColor, dark: UIColor) {

        self.init(dynamicProvider: { (traits) in
            switch traits.userInterfaceStyle {
            case .unspecified, .light: return light
            case .dark: return dark
            }
        })
    }
}

UIColor(light: .white, dark: .white) == UIColor(light: .white, dark: .white) // false

Текущее (неоптимальное решение)

func equals(_ object: Any?) -> Bool {
    guard let rhs = object as? UIColor else { return false }

    var lhsR: CGFloat = 0
    var lhsG: CGFloat = 0
    var lhsB: CGFloat = 0
    var lhsA: CGFloat = 0
    getRed(&lhsR, green: &lhsG, blue: &lhsB, alpha: &lhsA)

    var rhsR: CGFloat = 0
    var rhsG: CGFloat = 0
    var rhsB: CGFloat = 0
    var rhsA: CGFloat = 0
    rhs.getRed(&rhsR, green: &rhsG, blue: &rhsB, alpha: &rhsA)

    return  lhsR == rhsR && lhsG == rhsG && lhsB == rhsB && lhsA == rhsA
}

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

Но гораздо лучшим решением было бы сравнение каждого представления цвета с использованием resolvedColor(with:). Но это должно быть реализовано Apple, чтобы мы могли продолжать использовать == над протоколом Equatable.


person blackjacx    schedule 08.08.2019    source источник
comment
Добавьте код, который вы пробовали до сих пор,   -  person PGDev    schedule 08.08.2019
comment
Готово - спасибо за подсказку.   -  person blackjacx    schedule 08.08.2019
comment
Сравнение динамических цветов с xcassets работает как положено, но я не знаю, сможете ли вы его использовать.   -  person Grubas    schedule 25.02.2020
comment
Альтернативой является stackoverflow.com/a/58398769/1071510, но это не сработает для NSAttributedString.   -  person Grubas    schedule 25.02.2020
comment
@Grubas нет, по-видимому, нет, поскольку у нас есть много приложений с белой маркировкой, которые повторно используют существующие цвета (например, цвет текста), и поэтому мы должны создавать их в коде.   -  person blackjacx    schedule 26.02.2020


Ответы (1)


Попробуйте использовать === вместо ==

UIColor(light: .white, dark: .white) === UIColor(light: .white, dark: .white)
person PGDev    schedule 08.08.2019
comment
Это не работает для меня, так как мне (и NSAttributedString) нужно равенство по компонентам (==), а не по указателю (===). Пример UIColor(red: 0, green: 0, blue: 0, alpha: 0) === UIColor(red: 0, green: 0, blue: 0, alpha: 0) например. уже возвращает false, что означает, что использование динамического провайдера также не будет работать в этом случае. - person blackjacx; 08.08.2019