Làm thế nào để so sánh UIColors?


127

Tôi muốn kiểm tra bộ màu cho nền trên UIImageView. Tôi đã thử:

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

nhưng điều đó không hiệu quả, ngay cả khi tôi biết màu là màu xanh lá cây, nó luôn rơi vào phần khác.

Ngoài ra, có một cách để xuất màu hiện tại trong bảng điều khiển gỡ lỗi.

p [myimage backgroundColor]

po [myimage backgroundColor]

đừng làm việc

Câu trả lời:


176

Bạn đã thử [myColor isEqual:someOtherColor]chưa


Cảm ơn. Sự khác biệt với isEqualTo là gì? Ngoài ra, bạn có biết làm thế nào để hiển thị nó trong trình gỡ lỗi?
Không gian thứ

93
Nhân tiện: Hãy cẩn thận khi so sánh màu sắc theo cách này, bởi vì chúng phải nằm trong cùng một mô hình màu để được coi là bằng nhau. Chẳng hạn, # ffffffkhông bằng [UIColor whiteColor].
zoul

2
Zoul điểm tốt, có thể hữu ích hơn để chỉ ra một giải pháp không chỉ là vấn đề mặc dù = D
pfrank

11
Điểm tốt Pfrank, có thể hữu ích hơn để chỉ ra một giải pháp không chỉ là vấn đề mặc dù = D
Albert Renshaw

Không phải lúc nào tôi cũng làm việc khi so sánh một nút.tintColor với màu tôi đã đặt. Phải làm với làm tròn. Nếu bạn gặp phải điều này, hãy xem câu trả lời của tôi dưới đây.
Pbk

75

Như zoul đã chỉ ra trong các bình luận, isEqual:sẽ trở lại NOkhi so sánh các màu trong các mô hình / không gian khác nhau (ví dụ #FFFvới [UIColor whiteColor]). Tôi đã viết phần mở rộng UIColor này để chuyển đổi cả hai màu thành cùng một không gian màu trước khi so sánh chúng:

- (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
Đẹp, nhưng có một rò rỉ tôi nghĩ. Bạn không bao giờ phát hành CGColorCreate ở giữa.
mượn

Đây là một giải pháp hoàn hảo!
Alones

Bạn có thể giải thích những gì đang xảy ra với carat? Tôi không nghĩ rằng tôi đã thấy cú pháp đó trước đây.
Victor Engel

@VictorEngel, UIColor *(^convertColorToRGBSpace)(UIColor*) = ^(UIColor *color) ...đang khai báo a block. Anh dùng nó sau convertColorToRGBSpace(self). Để biết phần giới thiệu về các khối trong iOS, hãy xem raywenderlich.com/9328/creating-a-diner-app-USE-blocks-part-1
JRG-Developer

1
Tôi sử dụng tất cả các khối, nhưng tôi chưa bao giờ thấy cú pháp như thế này trước đây. Tôi đoán có lẽ tôi đã không sử dụng một khối trả về một đối tượng. Đó là những gì ở phía bên trái của = mà tôi đã đăng.
Victor Engel

65

Điều này có thể hơi muộn, nhưng CoreGraphics có API dễ dàng hơn để đạt được điều này:

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

Giống như các tài liệu nói:

Cho biết hai màu có bằng nhau không. Hai màu bằng nhau nếu chúng có không gian màu bằng nhau và các thành phần màu bằng nhau.

Điều này giải quyết rất nhiều rắc rối và thuật toán rò rỉ / tùy chỉnh.


5
[UIColor isEqual:]Liệu điều tương tự như thế này, phải không? Câu trả lời của Mark vẫn là người duy nhất kiểm tra sự tương đương mặc dù không gian màu tốt.
mattsven

9
Điều này không giúp ích gì nhiều hơn UIColor isEqual:nếu màu sắc ở các không gian màu khác nhau.
Echelon

Câu hỏi liên quan đến so sánh UIColor, không phải so sánh CGColor.
Sean Vikoren

Chính xác hơn tất cả các giải pháp khác :) +1 từ tôi
Nirav Gadhiya

8

giải pháp của samvermette được dịch sang swift:

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, đó là định lý Pythagore
Viktor Goltvyanitsa

6

Tiện ích mở rộng UIColor này hoạt động tốt với điều kiện là các màu được so sánh có thể được chuyển đổi sang định dạng RGB, nên hầu hết các trường hợp.

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

Ít nhất là với phần mở rộng này:

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

Cả hai so sánh sẽ trả về sai nếu so sánh bằng UColor.isEqual (...)


5

Tôi đã viết thể loại này. Nếu isEqual:không trả về NO, nó sẽ kiểm tra nếu so sánh thêm các thành phần khác nhau có thể vẫn khớp. Nếu có thể, các mô hình khác nhau vẫn được so sánh.

@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

Khi bạn so sánh myimage.backgroundColor == [UIColor greenColor]như thế này nếu bạn không thay đổi màu nền thành màu xanh trước câu lệnh đó thì nó không hoạt động.

Tôi đã gặp vấn đề tương tự trong trò chơi màu của mình và tôi đã giải quyết điều đó bằng cách sử dụng phương trình sai phân đơn giản trong màu RGB, bạn có thể nhanh chóng xem qua mẫu mã ngắn ColorProcess từ đây

giống như người chiến thắng trả lời

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{

}

Thay vì mẫu mã đó, bạn có thể sử dụng

include "UIColorProcess.h"

..

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

và tất nhiên nếu nó trả về 0 có nghĩa là bạn đang so sánh màu quá giống nhau. phạm vi trả về là một cái gì đó như (0,0f - 1,5f) ..


color.red/blue/green không được hỗ trợ cho tất cả các loại lớp màu khác nhau, hãy kiểm tra tài liệu
pfrank

1

Một số lỗi làm tròn kỳ lạ có thể xảy ra. Đó có thể là lý do một đối tượng được đặt thành màu và màu bạn đặt không khớp chính xác.

Đây là cách tôi giải quyết nó:

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

}

Mã này có thể được cải thiện bằng cách không chỉ so sánh 1 mà còn so sánh tất cả các thành phần. Ví dụ: đỏ + xanh + xanh + alpha == red2 + green2 + blue2 + alpha2


1
Màu sắc không giống nhau nếu chỉ được so sánh bởi thành phần màu xanh lá cây
Ben Sinclair

Đây là câu trả lời duy nhất đề cập và cố gắng giải quyết các lỗi làm tròn tiềm năng có thể tăng lên trong khi so sánh các màu được đặt thông qua các phương tiện khác nhau; vì vậy, trong khi nó chỉ tập trung vào màu xanh lá cây, ví dụ (như tác giả của câu trả lời đề cập) có thể được khái quát. Như vậy, và vì làm tròn thực tế là vấn đề tôi gặp phải, tôi đã thấy câu trả lời này hữu ích.
Matt Wagner

1

Tôi đang sử dụng tiện ích mở rộng này hoạt động cho tôi trong mọi trường hợp.

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

Hy vọng giúp một số.

Lưu ý: #ffffffkhông bằng [UIColor whiteColor]phần mở rộng này


Điều này có hoạt động trong khi so sánh màu sắc giữa các không gian màu?
Vaddadi Kartick

Không chắc chắn, tôi đã không thử nó cho tất cả các không gian màu.
arunit21

1

Các giải pháp khác không hoạt động chính xác. Đây là một cách tiếp cận hoạt động trong Swift:

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

Thế còn:

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

điều này có thể không hoạt động cho các trường hợp cạnh như một màu mẫu. từ doc Nếu màu nằm trong không gian màu tương thích, màu được chuyển thành định dạng RGB và các thành phần của nó được trả về ứng dụng của bạn. Nếu màu không nằm trong không gian màu tương thích, các tham số không thay đổi. Vì vậy, bạn có thể khởi tạo mỗi float với -1và nếu vẫn còn giá trị này sau khi gọi getRed:green:blue:alpha:, bạn biết so sánh không thành công. (hoặc không bỏ qua boolean được trả lại vì nó sẽ cho bạn biết nếu nó được gọi thành công.)
vikingosegundo

1
Tôi chỉ kiểm tra: mặc dù có thể kiểm tra màu đơn sắc theo màu RGBA trên lý thuyết, nhưng nó sẽ không hoạt động với mã của bạn, vì getRed:free:blue:alpha:sẽ không thành công với màu đơn sắc. Vì vậy, mã của bạn sẽ không mang lại kết quả khác hơn is equal:. xin vui lòng xem câu trả lời của tôi làm thế nào để đối phó với nó.
vikingosegundo

+1 cho sự kỹ lưỡng! Đoạn mã trên hoạt động cho trường hợp đơn giản của tôi, nhưng có vẻ như nó không phải là viên đạn bạc. Đồ tốt.
dooleyo

0

Đây là một tiện ích mở rộng để chuyển sang Màu không gian RGC trong 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

Mở rộng sang UIColor, sử dụng các tính năng Swift 2.2. Tuy nhiên, lưu ý rằng vì các giá trị RGBA được so sánh và đây là CGFloat, các lỗi làm tròn có thể làm cho các màu không được trả về như nhau nếu chúng không giống hệt nhau (ví dụ: chúng không được tạo ban đầu bằng các thuộc tính chính xác trong init (...)!).

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

Mở rộng 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

Tôi đã chuyển đổi câu trả lời của raf sang Swift 4 (rất nhiều thay đổi trong CGColorAPI), loại bỏ lực lượng hủy bỏ và giảm thụt nhờ sử dụng rộng rãi 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

Tại sao không thêm phần mở rộng với giao thức tương đương? Câu trả lời này là sử dụng giải pháp của Nicolas Miari. Vì vậy, nếu bạn thích câu trả lời này, xin vui lòng thích câu trả lời của anh ấy (thứ hai từ trên xuống)

Nhận xét của Zoul: Hãy cẩn thận khi so sánh màu sắc theo cách này, bởi vì chúng phải nằm trong cùng một mô hình màu để được coi là bằng nhau. Chẳng hạn, #ffffff không bằng [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

Mặc dù câu trả lời của @ samvermette rất hay, tôi đã thấy rằng đôi khi nó có thể dẫn đến phủ định sai khi so sánh các loại màu khác nhau (trong trường hợp của tôi UIDeviceRGBColorUICachedDeviceWhiteColor). Tôi cũng đã sửa nó bằng cách tạo màu rõ ràng trong 'other':

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


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.