เปรียบเทียบ UIColors อย่างไร?


127

ฉันต้องการตรวจสอบชุดสีสำหรับพื้นหลังบน UIImageView ฉันพยายามแล้ว:

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

แต่มันไม่ได้ผลแม้ว่าฉันจะรู้ว่าสีเป็นสีเขียว แต่ก็ยังตกอยู่ในส่วนอื่นเสมอ

นอกจากนี้ยังมีวิธีในการส่งออกสีปัจจุบันในคอนโซลการแก้ปัญหา

p [myimage backgroundColor]

และ

po [myimage backgroundColor]

ไม่ทำงาน.

คำตอบ:


176

คุณลองแล้ว[myColor isEqual:someOtherColor]หรือยัง?


ขอบคุณ isEqualTo ต่างกันอย่างไร? นอกจากนี้คุณรู้วิธีแสดงในดีบักเกอร์หรือไม่?
4thSpace

93
อย่างไรก็ตาม: โปรดใช้ความระมัดระวังในการเปรียบเทียบสีด้วยวิธีนี้เนื่องจากต้องอยู่ในรุ่นสีเดียวกันจึงจะถือว่าเท่ากัน ยกตัวอย่างเช่น # ไม่เท่ากับffffff [UIColor whiteColor]
zoul

2
จุดดี Zoul อาจมีประโยชน์มากกว่าในการชี้ไปที่วิธีแก้ปัญหาไม่ใช่แค่ปัญหาเท่านั้น = D
เล่นพิเรน

11
จุดดีเล่นตลกอาจมีประโยชน์มากกว่าในการชี้ไปที่วิธีแก้ปัญหาไม่ใช่แค่ปัญหาเท่านั้น = D
Albert Renshaw

ไม่ได้ผลสำหรับฉันเสมอไปเมื่อเปรียบเทียบปุ่ม tintColor กับสีที่ฉันตั้งไว้ ต้องทำอย่างไรกับการปัดเศษ หากคุณพบสิ่งนี้โปรดดูคำตอบของฉันด้านล่าง
Pbk

75

ในฐานะที่เป็น zoul ชี้ให้เห็นในความคิดเห็นที่isEqual:จะกลับมาNOเมื่อเปรียบเทียบสีที่อยู่ในรูปแบบที่แตกต่างกัน / พื้นที่ (เช่น#FFFมี[UIColor whiteColor]) ฉันเขียนส่วนขยาย UIColor นี้ที่แปลงทั้งสองสีให้เป็นพื้นที่สีเดียวกันก่อนที่จะเปรียบเทียบ:

- (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
ดี แต่มีการรั่วไหลฉันคิดว่า คุณไม่เคยปล่อย CGColorCreate ตรงกลาง
borrrden

นี่คือทางออกที่สมบูรณ์แบบ!
เดียว

คุณอธิบายได้ไหมว่าเกิดอะไรขึ้นกับกะรัต? ฉันไม่คิดว่าฉันเคยเห็นไวยากรณ์นั้นมาก่อน
Victor Engel

@VictorEngel UIColor *(^convertColorToRGBSpace)(UIColor*) = ^(UIColor *color) ...กำลังประกาศกblock. เขาใช้มันในภายหลังด้วยconvertColorToRGBSpace(self). สำหรับข้อมูลเบื้องต้น
JRG-Developer

1
ฉันใช้บล็อก tine ทั้งหมด แต่ฉันไม่เคยเห็นไวยากรณ์แบบนี้มาก่อน ฉันเดาว่าฉันอาจจะไม่ได้ใช้บล็อกที่ส่งคืนวัตถุ มันคือสิ่งที่อยู่ทางซ้ายของ = ที่ฉันโพสต์เกี่ยวกับ
Victor Engel

65

สิ่งนี้อาจจะสายเกินไป แต่ CoreGraphics มี API ที่ง่ายกว่าเพื่อให้บรรลุสิ่งนี้:

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

เช่นเดียวกับเอกสารกล่าวว่า:

ระบุว่าสองสีเท่ากันหรือไม่ สองสีจะเท่ากันหากมีช่องว่างสีเท่ากันและส่วนประกอบของสีที่เป็นตัวเลขเท่ากัน

วิธีนี้ช่วยแก้ปัญหาและอัลกอริทึมที่รั่วไหล / กำหนดเองได้


5
[UIColor isEqual:]สิ่งเดียวกันกับสิ่งนี้หรือไม่? คำตอบของ Mark ยังคงเป็นคำตอบเดียวที่ตรวจสอบความเท่าเทียมกันแม้จะมีพื้นที่สีได้ดีก็ตาม
mattsven

9
สิ่งนี้ไม่ได้ช่วยอะไรมากไปกว่าUIColor isEqual:การที่สีอยู่ในช่องว่างสีที่ต่างกัน
Echelon

คำถามเกี่ยวกับการเปรียบเทียบ UIColor ไม่ใช่การเปรียบเทียบ CGColor
Sean Vikoren

แม่นยำกว่าโซลูชันอื่น ๆ ทั้งหมด :) +1 จากฉัน
Nirav Gadhiya

8

โซลูชันของ samvermette แปลเป็นรวดเร็ว:

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 มันคือทฤษฎีบทพีทาโกรัส
Viktor Goltvyanitsa

6

ส่วนขยาย UIColor นี้ใช้งานได้ดีหากสีที่เปรียบเทียบสามารถแปลงเป็นรูปแบบ RGB ได้ซึ่งส่วนใหญ่ควรเป็นกรณี

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
    }
}

อย่างน้อยก็มีส่วนขยายนี้:

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

การเปรียบเทียบทั้งสองจะส่งคืนเท็จหากเปรียบเทียบโดยใช้ UColor.isEqual (... )


5

ฉันเขียนหมวดหมู่นี้ หากisEqual:ไม่ส่งคืน NO จะทดสอบว่าการเปรียบเทียบส่วนประกอบต่าง ๆ อาจยังคงตรงกันหรือไม่ ถ้าเป็นไปได้ยังเทียบรุ่นต่างๆ

@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

เมื่อคุณเปรียบเทียบmyimage.backgroundColor == [UIColor greenColor]เช่นนี้หากคุณไม่ได้เปลี่ยน backgroundColor เป็นสีเขียวก่อนคำสั่งนั้นจะไม่ทำงาน

ฉันมีปัญหาเดียวกันในเกมสีของฉันและฉันแก้ไขโดยใช้สมการความแตกต่างอย่างง่ายในสี RGB คุณสามารถดูตัวอย่างโค้ดสั้น ๆ จากที่นี่ได้อย่างรวดเร็ว

มันเหมือนกับคำตอบของผู้ชนะ

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{

}

แทนที่จะเป็นตัวอย่างโค้ดนั้นคุณสามารถใช้ได้

include "UIColorProcess.h"

..

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

และแน่นอนว่าหากส่งกลับเป็น 0 นั่นหมายความว่าคุณกำลังเปรียบเทียบสีที่ใกล้เคียงกันเกินไป ช่วงผลตอบแทนเป็นอย่างเช่น (0.0f - 1.5f) ..


color.red/blue/green ไม่รองรับคลาสสีทุกประเภทตรวจสอบเอกสาร
เล่นพิเรน

1

ข้อผิดพลาดในการปัดเศษแปลก ๆ อาจเกิดขึ้นได้ นั่นอาจเป็นสาเหตุที่วัตถุตั้งค่าเป็นสีและสีที่คุณตั้งไว้ไม่ตรงกันทั้งหมด

นี่คือวิธีที่ฉันแก้ไข:

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))

}

โค้ดนี้สามารถปรับปรุงได้โดยไม่เพียง แต่เปรียบเทียบ 1 แต่เปรียบเทียบส่วนประกอบทั้งหมด เช่น red + green + blue + alpha == red2 + green2 + blue2 + alpha2


1
สีไม่เหมือนกันหากเทียบกับส่วนประกอบสีเขียวเท่านั้น
Ben Sinclair

นี่เป็นคำตอบเดียวที่กล่าวถึงและพยายามแก้ไขข้อผิดพลาดในการปัดเศษที่อาจเกิดขึ้นซึ่งสามารถครอบตัดในขณะที่เปรียบเทียบสีที่กำหนดด้วยวิธีการที่แตกต่างกัน ดังนั้นแม้ว่าจะเน้นเฉพาะสีเขียว แต่ตัวอย่าง (ตามที่ผู้เขียนคำตอบกล่าวถึง) สามารถสรุปได้ทั่วไป ด้วยเหตุนี้และเนื่องจากการปัดเศษเป็นปัญหาที่ฉันพบฉันพบว่าคำตอบนี้มีประโยชน์
Matt Wagner

1

ฉันใช้ส่วนขยายนี้ซึ่งใช้ได้ผลกับฉันในทุกกรณี

/***** 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 ****/

ความหวังช่วยบางคน

หมายเหตุ: #ffffffไม่เท่ากัน[UIColor whiteColor]โดยส่วนขยายนี้


ใช้งานได้ขณะเปรียบเทียบสีข้ามช่องว่างสีหรือไม่
Vaddadi Kartick

ไม่แน่ใจฉันยังไม่ได้ทดสอบสำหรับพื้นที่สีทั้งหมด
arunit21

0

สิ่งที่เกี่ยวกับ:

+(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);
}

ซึ่งอาจใช้ไม่ได้กับเคสขอบเป็นสีลวดลาย จาก doc หากสีอยู่ในพื้นที่สีที่เข้ากันได้สีจะถูกแปลงเป็นรูปแบบ RGB และส่วนประกอบจะถูกส่งกลับไปยังแอปพลิเคชันของคุณ หากสีไม่อยู่ในพื้นที่สีที่เข้ากันได้พารามิเตอร์จะไม่เปลี่ยนแปลง ดังนั้นคุณสามารถสร้างอินสแตนซ์แต่ละลอยด้วย-1และหากยังมีค่านี้อยู่หลังจากโทรgetRed:green:blue:alpha:คุณจะรู้ว่าการเปรียบเทียบล้มเหลว (หรืออย่าละเว้นบูลีนที่ส่งคืนเพราะมันจะบอกคุณว่าเรียกสำเร็จหรือไม่)
vikingosegundo

1
ฉันเพิ่งตรวจสอบ: แม้ว่าในทางทฤษฎีจะสามารถตรวจสอบขาวดำเทียบกับสี RGBA ได้ แต่ก็ใช้ไม่ได้กับรหัสของคุณเนื่องจากgetRed:free:blue:alpha:จะไม่ประสบความสำเร็จกับสีขาวดำ is equal:ดังนั้นรหัสของคุณจะไม่เกิดผลอีกกว่า โปรดดูคำตอบของฉันว่าจะจัดการกับมันอย่างไร
vikingosegundo

+1 เพื่อความทั่วถึง! รหัสด้านบนใช้ได้กับกรณีง่ายๆของฉัน แต่ดูเหมือนว่าจะไม่ใช่กระสุนเงิน สิ่งที่ดี.
dooleyo

0

นี่คือส่วนขยายสำหรับเปลี่ยนไปใช้ RGC Space Color ใน Swift:

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

ขยายไปยัง UIColor โดยใช้คุณสมบัติ Swift 2.2 อย่างไรก็ตามโปรดทราบว่าเนื่องจากมีการเปรียบเทียบค่า RGBA และสิ่งเหล่านี้เป็น CGFloat ข้อผิดพลาดในการปัดเศษอาจทำให้สีไม่ถูกส่งคืนเท่ากันหากไม่เหมือนกันทุกประการ (เช่นไม่ได้ถูกสร้างขึ้นโดยใช้คุณสมบัติเดียวกันในการเริ่มต้น ( ... )!)

/**
 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

- (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

ฉันมีแปลงคำตอบที่อากาศจะสวิฟท์ 4 (จำนวนมากของการเปลี่ยนแปลงในCGColorAPI), แกะแรงลบออกและลดลงเยื้องขอบคุณการใช้ใจกว้างของ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

ทำไมไม่เพิ่มส่วนขยายด้วยโปรโตคอลที่เท่าเทียมกัน? คำตอบนี้ใช้วิธีแก้ปัญหาของ Nicolas Miari ดังนั้นหากคุณชอบคำตอบนี้โปรดชอบคำตอบของเขา (อันดับที่สองจากด้านบน)

ข้อคิดเห็นของ Zoul: โปรดใช้ความระมัดระวังในการเปรียบเทียบสีด้วยวิธีนี้เนื่องจากต้องอยู่ในรุ่นสีเดียวกันจึงจะถือว่าเท่ากัน ตัวอย่างเช่น #ffffff ไม่เท่ากับ [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

ในขณะที่คำตอบ @ samvermette เป็นสิ่งที่ดีมากผมได้พบว่าบางครั้งมันก็จะนำไปสู่เชิงลบเท็จเมื่อเปรียบเทียบประเภทสีที่แตกต่างกัน (ในกรณีของฉันUIDeviceRGBColorไปUICachedDeviceWhiteColor) ฉันแก้ไขโดยการสร้างสีอย่างชัดเจนใน `` else 'ด้วย:

- (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];
}


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.