问题
I'm comparing two UIColor
initialised using the new iOS 13 init(dynamicProvider:)
https://developer.apple.com/documentation/uikit/uicolor/3238041-init
but that's what I get runtime when I compare them in unit test with an XCTAssertEqual
:
XCTAssertEqual failed: ("Optional(<UIDynamicProviderColor: {...};
provider = <__NSMallocBlock__: {...}>>)") is not equal to
("Optional(<UIDynamicProviderColor: {...}; provider = <__NSMallocBlock__: {...}>>)")
This is an example of how I create the color:
struct Style {
static var color: UIColor {
if #available(iOS 13.0, *) {
return UIColor { traitCollection in
return traitCollection.userInterfaceStyle == .dark ? .secondarySystemBackground : UIColor.white
}
} else {
return UIColor.white
}
}
}
The test code:
func testExample() {
XCTAssertEqual(Style.color, Style.color)
}
I tried overriding isEqual
method of UIColor
with an extension but apparently it's not called.
Do you have any workaround for this?
回答1:
One solution to your unit test is by changing your code to this:
XCTAssertEqual(Style.color.cgColor, yourExpectedColor.cgColor)
In the iOS 13 at runtime it is comparing two UIDynamicProviderColor objects that return an UIColor object after running a block "(UITraitCollection) -> UIColor". So, that's the reason you have two different objects. Getting the cgColor from both you can compare them correctly. I hope I was helpfull.
回答2:
Currently we do the following:
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
}
With this in place you cannot use ==
anymore but have to explicitly call this function when you want to compare colors.
But a much better solution would have to compare each representation of the color by using resolvedColor(with:)
. But this would have to be implemented by Apple so we can continue using ==
nad the Equatable
protocol.
来源:https://stackoverflow.com/questions/58065340/how-to-compare-two-uidynamicprovidercolor