Wie vergleiche ich UIColors?


127

Ich möchte den Farbsatz für einen Hintergrund in einer UIImageView überprüfen. Ich habe es versucht:

if(myimage.backgroundColor == [UIColor greenColor]){
...}
else{
...}

Aber das funktioniert nicht, auch wenn ich weiß, dass die Farbe grün ist, fällt sie immer in den anderen Teil.

Gibt es auch eine Möglichkeit, die aktuelle Farbe in der Debug-Konsole auszugeben?

p [myimage backgroundColor]

und

po [myimage backgroundColor]

arbeite nicht

Antworten:


176

Hast du es versucht [myColor isEqual:someOtherColor]?


Vielen Dank. Was ist der Unterschied zu isEqualTo? Wissen Sie auch, wie es im Debugger angezeigt wird?
4thSpace

93
Übrigens: Seien Sie vorsichtig, wenn Sie Farben auf diese Weise vergleichen, da sie sich im selben Farbmodell befinden müssen, um als gleich zu gelten. Zum Beispiel ist # ffffffnicht gleich [UIColor whiteColor].
Zoul

2
Guter Punkt Zoul, könnte nützlicher sein, um auf eine Lösung hinzuweisen, nicht nur auf das Problem = D
pfrank

11
Guter Punkt Pfrank, könnte nützlicher sein, um auf eine Lösung hinzuweisen, nicht nur auf das Problem = D
Albert Renshaw

Hat beim Vergleich einer button.tintColor mit der Farbe, auf die ich sie eingestellt hatte, nicht immer funktioniert. Hatte mit Rundung zu tun. Wenn Sie darauf stoßen, sehen Sie meine Antwort unten.
Pbk

75

Wie Zoul in den Kommentaren hervorhob, isEqual:wird NObeim Vergleich von Farben, die sich in verschiedenen Modellen / Räumen befinden (zum Beispiel #FFFmit [UIColor whiteColor]), zurückgegeben. Ich habe diese UIColor-Erweiterung geschrieben, die beide Farben in denselben Farbraum konvertiert, bevor ich sie vergleiche:

- (BOOL)isEqualToColor:(UIColor *)otherColor {
    CGColorSpaceRef colorSpaceRGB = CGColorSpaceCreateDeviceRGB();

    UIColor *(^convertColorToRGBSpace)(UIColor*) = ^(UIColor *color) {
        if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) == kCGColorSpaceModelMonochrome) {
            const CGFloat *oldComponents = CGColorGetComponents(color.CGColor);
            CGFloat components[4] = {oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1]};
            CGColorRef colorRef = CGColorCreate( colorSpaceRGB, components );

            UIColor *color = [UIColor colorWithCGColor:colorRef];
            CGColorRelease(colorRef);
            return color;            
        } else
            return color;
    };

    UIColor *selfColor = convertColorToRGBSpace(self);
    otherColor = convertColorToRGBSpace(otherColor);
    CGColorSpaceRelease(colorSpaceRGB);

    return [selfColor isEqual:otherColor];
}

2
Schön, aber ich denke, es gibt ein Leck. Sie geben CGColorCreate niemals in der Mitte frei.
Borrrden

Dies ist eine perfekte Lösung!
Alleine

Können Sie erklären, was mit den Karat los ist? Ich glaube nicht, dass ich diese Syntax schon einmal gesehen habe.
Victor Engel

@ VictorEngel, UIColor *(^convertColorToRGBSpace)(UIColor*) = ^(UIColor *color) ...deklariert a block. Er benutzt es später mit convertColorToRGBSpace(self). Eine Einführung in Blöcke in iOS finden Sie unter raywenderlich.com/9328/creating-a-diner-app-using-blocks-part-1
JRG-Developer

1
Ich verwende alle Blöcke, aber ich habe noch nie eine solche Syntax gesehen. Ich glaube, ich habe keinen Block verwendet, der ein Objekt zurückgegeben hat. Es ist das, was sich auf der linken Seite des = befindet, über das ich geschrieben habe.
Victor Engel

65

Dies mag etwas zu spät sein, aber CoreGraphics verfügt über eine einfachere API, um dies zu erreichen:

CGColorEqualToColor(myColor.CGColor, [UIColor clearColor].CGColor)

Wie die Dokumentation sagt:

Gibt an, ob zwei Farben gleich sind. Zwei Farben sind gleich, wenn sie gleiche Farbräume und numerisch gleiche Farbkomponenten haben.

Dies löst viele Probleme und undichte / benutzerdefinierte Algorithmen.


5
[UIColor isEqual:]macht das Gleiche, nicht wahr? Marks Antwort ist immer noch die einzige, die die Äquivalenz trotz des Farbraums gut überprüft.
Mattsven

9
Dies hilft nicht mehr, als UIColor isEqual:wenn sich die Farben in unterschiedlichen Farbräumen befinden.
Echelon

Die Frage betrifft den UIColor-Vergleich, nicht den CGColor-Vergleich.
Sean Vikoren

Genauer als alle anderen Lösungen :) +1 von mir
Nirav Gadhiya

8

Samvermettes Lösung übersetzt in schnell:

extension UIColor {
    func isEqualToColor(otherColor : UIColor) -> Bool {
        if self == otherColor {
            return true
        }

        let colorSpaceRGB = CGColorSpaceCreateDeviceRGB()
        let convertColorToRGBSpace : ((color : UIColor) -> UIColor?) = { (color) -> UIColor? in
            if CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) == CGColorSpaceModel.Monochrome {
                let oldComponents = CGColorGetComponents(color.CGColor)
                let components : [CGFloat] = [ oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1] ]
                let colorRef = CGColorCreate(colorSpaceRGB, components)
                let colorOut = UIColor(CGColor: colorRef!)
                return colorOut
            }
            else {
                return color;
            }
        }

        let selfColor = convertColorToRGBSpace(color: self)
        let otherColor = convertColorToRGBSpace(color: otherColor)

        if let selfColor = selfColor, otherColor = otherColor {
            return selfColor.isEqual(otherColor)
        }
        else {
            return false
        }
    }
}

7
#import "UIColor-Expanded.h"
//https://github.com/thetaplab/uicolor-utilities

//RGB distance
CGFloat distance = sqrtf(powf((clr0.red - clr1.red), 2) + powf((clr0.green - clr1.green), 2) + powf((clr0.blue - clr1.blue), 2) );
if(distance<=minDistance){
....
}else{
...
}

@ Rudolf Adamkovic, es ist Satz von Pythagoras
Viktor Goltvyanitsa

6

Diese UIColor-Erweiterung funktioniert einwandfrei, vorausgesetzt, die verglichenen Farben können in das RGB-Format konvertiert werden, was in den meisten Fällen der Fall sein sollte.

public extension UIColor {

    static func == (l: UIColor, r: UIColor) -> Bool {
        var l_red = CGFloat(0); var l_green = CGFloat(0); var l_blue = CGFloat(0); var l_alpha = CGFloat(0)
        guard l.getRed(&l_red, green: &l_green, blue: &l_blue, alpha: &l_alpha) else { return false }
        var r_red = CGFloat(0); var r_green = CGFloat(0); var r_blue = CGFloat(0); var r_alpha = CGFloat(0)
        guard r.getRed(&r_red, green: &r_green, blue: &r_blue, alpha: &r_alpha) else { return false }
        return l_red == r_red && l_green == r_green && l_blue == r_blue && l_alpha == r_alpha
    }
}

Zumindest mit dieser Erweiterung:

UIColor.whiteColor == UIColor(hex: "#FFFFFF") // true
UIColor.black == UIColor(red: 0, green: 0, blue: 0, alpha: 1) // true

Beide Vergleiche würden false ergeben, wenn sie mit der nativen UColor.isEqual (...) verglichen würden.


5

Ich habe diese Kategorie geschrieben. Wenn isEqual:NO zurückgegeben wird, wird geprüft, ob der weitere Vergleich verschiedener Komponenten möglicherweise noch übereinstimmt. Wenn möglich, werden noch verschiedene Modelle verglichen.

@implementation UIColor (Matching)


-(BOOL)matchesColor:(UIColor *)color error:(NSError *__autoreleasing *)error
{
    UIColor *lhs = self;
    UIColor *rhs = color;

    if([lhs isEqual:rhs]){ // color model and values are the same
        return YES;
    }

    CGFloat red1, red2, green1, alpha1, green2, blue1, blue2, alpha2;
    BOOL lhsSuccess = [lhs getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
    BOOL rhsSuccess = [rhs getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];
    if((!lhsSuccess && rhsSuccess) || (lhsSuccess && !rhsSuccess)){ // one is RGBA, one color not.
        CGFloat r,g,b,a;
        if(!lhsSuccess){ // lhs color could be a monochrome
            const CGFloat *components = CGColorGetComponents(lhs.CGColor);
            if([lhs _colorSpaceModel] == kCGColorSpaceModelMonochrome){
                r = g = b = components[0];
                a = components[1];

                return r == red2 && g == green2 && b == blue2 && a == alpha2;
            }
        } else {  // rhs color could be a monochrome
            const CGFloat *components = CGColorGetComponents(rhs.CGColor);

            if([rhs _colorSpaceModel] == kCGColorSpaceModelMonochrome){
                r = g = b = components[0];
                a = components[1];
                return r == red1 && g == green1 && b == blue1 && a == alpha1;
            }
        }


        NSError *aError = [[NSError alloc] initWithDomain:@"UIColorComparision" code:-11111 userInfo:[self _colorComparisionErrorUserInfo]];
        *error = aError;
        return  NO;
    } else if (!lhsSuccess && !rhsSuccess){ // both not RGBA, lets try HSBA
        CGFloat hue1,saturation1,brightness1;
        CGFloat hue2,saturation2,brightness2;

        lhsSuccess = [lhs getHue:&hue1 saturation:&saturation1 brightness:&brightness1 alpha:&alpha1];
        rhsSuccess = [lhs getHue:&hue2 saturation:&saturation2 brightness:&brightness2 alpha:&alpha2];
        if((!lhsSuccess && rhsSuccess) || (lhsSuccess && !rhsSuccess)){
            NSError *aError = [[NSError alloc] initWithDomain:@"UIColorComparision" code:-11111 userInfo:[self _colorComparisionErrorUserInfo]];
            *error = aError;
            return  NO;
        } else if(!lhsSuccess && !rhsSuccess){ // both not HSBA, lets try monochrome
            CGFloat white1, white2;

            lhsSuccess = [lhs getWhite:&white1 alpha:&alpha1];
            rhsSuccess = [rhs getWhite:&white2 alpha:&alpha2];
            if((!lhsSuccess && rhsSuccess) || (lhsSuccess && !rhsSuccess)){
                NSError *aError = [[NSError alloc] initWithDomain:@"UIColorComparision" code:-11111 userInfo:[self _colorComparisionErrorUserInfo]];
                *error = aError;
                return  NO;
            } else {
                return white1 == white2 && alpha1 == alpha2;
            }

        } else {
            return hue1 == hue2 && saturation1 == saturation2 && brightness1 == brightness2 && alpha1 == alpha2;
        }

    } else {
        return (red1 == red2 && green1 == green2 && blue1 == blue2 && alpha1 == alpha2);

    }
}

-(NSDictionary *)_colorComparisionErrorUserInfo{

    NSDictionary *userInfo = @{
                               NSLocalizedDescriptionKey: NSLocalizedString(@"Comparision failed.", nil),
                               NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The colors models are incompatible. Or the color is a pattern.", nil),

                               };
    return userInfo;
}

- (CGColorSpaceModel)_colorSpaceModel {
    return CGColorSpaceGetModel(CGColorGetColorSpace(self.CGColor));
}

@end

UIColor *green1 = [UIColor greenColor];
UIColor *green2 = [UIColor colorWithRed:0 green:1 blue:0 alpha:1];
UIColor *yellow = [UIColor yellowColor];
UIColor *grey1  = [UIColor colorWithWhite:2.0/3.0 alpha:1];
UIColor *grey2  = [UIColor lightGrayColor];

NSError *error1, *error2, *error3, *error4, *error5;

BOOL match1 = [green1 matchesColor:green2 error:&error1];   // YES
BOOL match2 = [green1 matchesColor:yellow error:&error2];   // NO
BOOL match3 = [green1 matchesColor:grey1 error:&error3];    // NO
BOOL match4 = [grey1 matchesColor:grey2 error:&error4];     // YES
BOOL match5 = [grey1 matchesColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]]
                            error:&error5];                 // NO, Error

2

Wenn Sie myimage.backgroundColor == [UIColor greenColor]wie folgt vergleichen, wenn Sie die Hintergrundfarbe vor dieser Anweisung nicht in Grün geändert haben, funktioniert sie nicht.

Ich hatte das gleiche Problem in meinem Farbspiel und habe gelöst, dass Sie mithilfe der einfachen Differenzgleichung in RGB-Farben schnell einen Blick auf das kurze Codebeispiel ColorProcess werfen können hier

Es ist wie die Antwort der Sieger

GFloat distance = sqrtf(powf((clr0.red - clr1.red), 2) + powf((clr0.green - clr1.green), 2) + powf((clr0.blue - clr1.blue), 2) );
if(distance<=minDistance){
....
}else{

}

Anstelle dieses Codebeispiels können Sie verwenden

include "UIColorProcess.h"

..

float distance = [UIColorProcess findDistanceBetweenTwoColor:[UIColor redColor] secondColor:[UIColor blueColor]];

und wenn 0 zurückgegeben wird, bedeutet dies natürlich, dass Sie eine zu ähnliche Farbe vergleichen. Rückgabebereich ist so etwas wie (0.0f - 1.5f) ..


color.red/blue/green wird nicht für alle Arten von Farbklassen unterstützt. Überprüfen Sie die Dokumente
pfrank

1

Einige seltsame Rundungsfehler können auftreten. Dies kann der Grund sein, warum ein Objekt auf eine Farbe eingestellt ist und die Farbe, auf die Sie es eingestellt haben, nicht genau übereinstimmt.

So habe ich es gelöst:

private func compareColors (c1:UIColor, c2:UIColor) -> Bool{
    // some kind of weird rounding made the colors unequal so had to compare like this

    var red:CGFloat = 0
    var green:CGFloat  = 0
    var blue:CGFloat = 0
    var alpha:CGFloat  = 0
    c1.getRed(&red, green: &green, blue: &blue, alpha: &alpha)

    var red2:CGFloat = 0
    var green2:CGFloat  = 0
    var blue2:CGFloat = 0
    var alpha2:CGFloat  = 0
    c2.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2)

    return (Int(green*255) == Int(green2*255))

}

Dieser Code kann verbessert werden, indem nicht nur 1, sondern alle Komponenten verglichen werden. ZB rot + grün + blau + alpha == rot2 + grün2 + blau2 + alpha2


1
Die Farben sind nicht die gleichen, wenn sie nur mit der grünen Komponente verglichen werden
Ben Sinclair

Dies ist die einzige Antwort, die potenzielle Rundungsfehler erwähnt und versucht, die auftreten können, wenn Farben verglichen werden, die auf unterschiedliche Weise festgelegt wurden. Während es sich also nur um Grün handelt, kann das Beispiel (wie der Autor der Antwort erwähnt) verallgemeinert werden. Als solches und da das Runden tatsächlich das Problem war, auf das ich stieß, fand ich diese Antwort hilfreich.
Matt Wagner

1

Ich verwende diese Erweiterung, die in allen Fällen für mich funktioniert.

/***** UIColor Extension to Compare colors as string *****/
@interface UIColor (compare)
- (BOOL)compareWithColor:(UIColor *)color;
@end

@implementation UIColor(compare)
- (BOOL)compareWithColor:(UIColor *)color {
    return ([[[CIColor colorWithCGColor:self.CGColor] stringRepresentation] isEqualToString:[[CIColor colorWithCGColor:color.CGColor] stringRepresentation]]);
}
@end
/**** End ****/

Hoffnung hilft jemandem.

Hinweis: #ffffffEntspricht [UIColor whiteColor]dieser Erweiterung


Funktioniert dies beim Vergleichen von Farben über Farbräume hinweg?
Vaddadi Kartick

Ich bin mir nicht sicher, ob ich es nicht für alle Farbräume getestet habe.
Arunit21

1

Die anderen Lösungen funktionierten nicht richtig. Hier ist ein Ansatz, der in Swift funktioniert:

import CoreGraphics

extension UIColor {

    /**
     Checks for visual equality of two colors regardless of their color space.
     - parameter    color:  The other color for comparison.
     - returns:     A boolean representing whether the colors are visually the same color.
     */
    public func isVisuallyEqualTo(_ color: UIColor) -> Bool {
        return rgbaComponents == color.rgbaComponents
    }

    public var rgbaComponents: [CGFloat] {
        var data = [CUnsignedChar](repeating: 0, count: 4)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let context = CGContext(data: &data,
                                width: 1, height: 1,
                                bitsPerComponent: 8, bytesPerRow: 4,
                                space: colorSpace,
                                bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue)
        context?.setFillColor(cgColor)
        context?.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
        return data.map { CGFloat($0) / 255.0 }
    }

}

0

Wie wäre es mit:

+(BOOL)color:(UIColor *)color1 matchesColor:(UIColor *)color2
{
    CGFloat red1, red2, green1, green2, blue1, blue2, alpha1, alpha2;
    [color1 getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
    [color2 getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];

    return (red1 == red2 && green1 == green2 && blue1 == blue2 && alpha1 == alpha2);
}

Dies funktioniert möglicherweise nicht für Kantenfälle als Musterfarbe. from doc Wenn sich die Farbe in einem kompatiblen Farbraum befindet, wird die Farbe in das RGB-Format konvertiert und ihre Komponenten werden an Ihre Anwendung zurückgegeben. Befindet sich die Farbe nicht in einem kompatiblen Farbraum, bleiben die Parameter unverändert. Sie können also jeden Float mit instanziieren, -1und wenn einer nach dem Aufruf noch diesen Wert hat getRed:green:blue:alpha:, wissen Sie, dass der Vergleich fehlgeschlagen ist. (oder lassen Sie den zurückgegebenen Booleschen
Wert nicht weg,

1
Ich habe gerade überprüft: Obwohl es theoretisch möglich ist, Monochrom mit RGBA-Farben zu vergleichen, funktioniert es nicht mit Ihrem Code, da dies getRed:free:blue:alpha:bei einer Monochromfarbe nicht erfolgreich ist. Ihr Code liefert also kein anderes Ergebnis als is equal:. Bitte sehen Sie meine Antwort, wie ich damit umgehen soll.
Vikingosegundo

+1 für Gründlichkeit! Der obige Code funktioniert für meinen einfachen Fall, aber es scheint, dass es keine Silberkugel ist. Gutes Zeug.
Dooleyo

0

Hier ist eine Erweiterung, um in Swift zur RGC Space Color zu wechseln:

extension UIColor {

func convertColorToRGBSpaceColor() -> UIColor {
    let colorSpaceRGB = CGColorSpaceCreateDeviceRGB()
    let oldComponents = CGColorGetComponents(self.CGColor)
    let components = [oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1]]
    let colorRef = CGColorCreate(colorSpaceRGB, components)
    let convertedColor = UIColor(CGColor: colorRef!)
    return convertedColor
}

}}


0

Erweiterung auf UIColor mit Swift 2.2-Funktionen. Beachten Sie jedoch, dass Rundungsfehler dazu führen können, dass die Farben nicht als gleich zurückgegeben werden, wenn die RGBA-Werte verglichen werden und es sich um CGFloat handelt, wenn sie nicht exakt gleich sind (z. B. wurden sie ursprünglich nicht mit genau denselben Eigenschaften im Init erstellt (...)!).

/**
 Extracts the RGBA values of the colors and check if the are the same.
 */

public func isEqualToColorRGBA(color : UIColor) -> Bool {
    //local type used for holding converted color values
    typealias colorType = (red : CGFloat, green : CGFloat, blue : CGFloat, alpha : CGFloat)
    var myColor         : colorType = (0,0,0,0)
    var otherColor      : colorType = (0,0,0,0)
    //getRed returns true if color could be converted so if one of them failed we assume that colors are not equal
    guard getRed(&myColor.red, green: &myColor.green, blue: &myColor.blue, alpha: &myColor.alpha) &&
        color.getRed(&otherColor.red, green: &otherColor.green, blue: &otherColor.blue, alpha: &otherColor.alpha)
        else {
            return false
    }
    log.debug("\(myColor) = \(otherColor)")
    //as of Swift 2.2 (Xcode 7.3.1), tuples up to arity 6 can be compared with == so this works nicely
    return myColor == otherColor
}

0

UIColor-Erweiterung

- (CGFloat)accuracyCompareWith:(UIColor *)color {
    CIColor *c1 = [[CIColor alloc] initWithColor:self];
    CIColor *c2 = [[CIColor alloc] initWithColor:color];

    BOOL hasAlpha = c1.numberOfComponents == 4 && c2.numberOfComponents == 4;
    NSInteger numberOfComponents = hasAlpha ? 4 : 3;

    CGFloat colorMax = 1.0;
    CGFloat p = colorMax / 100.0;

    CGFloat redP = fabs(c1.red / p - c2.red / p);
    CGFloat greenP = fabs(c1.green / p - c2.green / p);
    CGFloat blueP = fabs(c1.blue / p - c2.blue / p);
    CGFloat alphaP = 0;

    if (hasAlpha)
        alphaP = fabs(c1.alpha / p - c2.alpha / p);

    return (redP + greenP + blueP + alphaP) / (CGFloat)numberOfComponents;
}

0

Ich habe die Antwort von raf auf Swift 4 konvertiert (viele Änderungen in der CGColorAPI), das Entpacken von Gewalt entfernt und die Einrückung verringert, dank der großzügigen Verwendung von guard:

@extension UIColor {
    func isEqualToColor(otherColor: UIColor) -> Bool {
        if self == otherColor {
            return true
        }
        let colorSpaceRGB = CGColorSpaceCreateDeviceRGB()
        let convertColorToRGBSpace: ((UIColor) -> UIColor?) = { (color) -> UIColor? in
            guard color.cgColor.colorSpace?.model == .monochrome else {
                return color
            }
            guard let oldComponents = color.cgColor.components else {
                return nil
            }
            let newComponents = [oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1]]
            guard let colorRef = CGColor(colorSpace: colorSpaceRGB, components: newComponents) else {
                    return nil
            }
            return UIColor(cgColor: colorRef)
        } 

        guard let selfColor = convertColorToRGBSpace(self), 
              let otherColor = convertColorToRGBSpace(otherColor) else {
            return false
        }
        return selfColor.isEqual(otherColor)
    }
}

0

Warum nicht die Erweiterung mit gleichwertigem Protokoll hinzufügen? Diese Antwort verwendet die Lösung von Nicolas Miari. Wenn Ihnen diese Antwort gefällt, können Sie auch gerne seine Antwort mögen (zweite von oben).

Der Kommentar von Zoul: Seien Sie vorsichtig, wenn Sie Farben auf diese Weise vergleichen, da sie sich im selben Farbmodell befinden müssen, um als gleich zu gelten. Zum Beispiel ist #ffffff nicht gleich [UIColor whiteColor]

static func == (lhs: UIColor, rhs: UIColor) -> Bool {

    let colorSpaceRGB = CGColorSpaceCreateDeviceRGB()
    let convertColorToRGBSpace: ((UIColor) -> UIColor?) = { (color) -> UIColor? in
        guard color.cgColor.colorSpace?.model == .monochrome else {
            return color
        }
        guard let oldComponents = color.cgColor.components else {
            return nil
        }
        let newComponents = [oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1]]
        guard let colorRef = CGColor(colorSpace: colorSpaceRGB, components: newComponents) else {
            return nil
        }
        return UIColor(cgColor: colorRef)
    }

    guard let selfColor = convertColorToRGBSpace(lhs),
        let otherColor = convertColorToRGBSpace(rhs) else {
            return false
    }
    return selfColor.isEqual(otherColor)
}

0

Obwohl die Antwort von @ samvermette sehr gut ist, habe ich festgestellt, dass sie manchmal zu falsch negativen Ergebnissen führen kann, wenn verschiedene Farbtypen verglichen werden (in meinem Fall UIDeviceRGBColormit UICachedDeviceWhiteColor). Ich habe es behoben, indem ich die Farbe auch explizit im "else" erstellt habe:

- (BOOL)isEqualToColor:(UIColor *)otherColor
{
    if (self == otherColor)
        return YES;

    CGColorSpaceRef colorSpaceRGB = CGColorSpaceCreateDeviceRGB();

    UIColor *(^convertColorToRGBSpace)(UIColor*) = ^(UIColor *color)
    {
        if (CGColorSpaceGetModel(CGColorGetColorSpace(color.CGColor)) == kCGColorSpaceModelMonochrome)
        {
            const CGFloat *oldComponents = CGColorGetComponents(color.CGColor);
            CGFloat components[4] = {oldComponents[0], oldComponents[0], oldComponents[0], oldComponents[1]};
            CGColorRef colorRef = CGColorCreate(colorSpaceRGB, components);
            UIColor *color = [UIColor colorWithCGColor:colorRef];
            CGColorRelease(colorRef);
            return color;
        }
        else
        {
            const CGFloat *oldComponents = CGColorGetComponents(color.CGColor);
            CGFloat components[4] = {oldComponents[0], oldComponents[1], oldComponents[2], oldComponents[3]};
            CGColorRef colorRef = CGColorCreate(colorSpaceRGB, components);
            UIColor *color = [UIColor colorWithCGColor:colorRef];
            CGColorRelease(colorRef);
            return color;
        }
    };

    UIColor *selfColor = convertColorToRGBSpace(self);
    otherColor = convertColorToRGBSpace(otherColor);
    CGColorSpaceRelease(colorSpaceRGB);

    return [selfColor isEqual:otherColor];
}

0

Du musst benutzen

BOOL equalColors = CGColorEqualToColor(uiColor1.CGColor, uiColor2.CGColor));

Dokumentation hier .


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.