【问题标题】:Comparing equality of [UIColor colorWithPatternImage:]比较 [UIColor colorWithPatternImage:] 的相等性
【发布时间】:2015-06-18 18:51:24
【问题描述】:

我想比较使用 [UIColor colorWithPatternImage:] 生成的两个 UIColor 是否相等。我似乎无法弄清楚如何做到这一点。

[[UIColor colorWithPatternImage:[UIImage imageNamed:@"camo2"]] isEqual:
[UIColor colorWithPatternImage:[UIImage imageNamed:@"camo2"]]]

无论我使用 == 还是 isEqual,总是返回 false。有人知道我想是否可以正确比较 colorWithPatternImages 或 CGPatterns 吗?我也尝试过比较 CGColorGetPattern(color.CGColor) 但这也不起作用。

编辑:这样做的原因是我有一个函数,它接受 UIColor 并给我一个 NSString 用于显示给用户。

+(NSString *)colorNameForColor:(UIColor *)color {

    if ([color isEqual:[UIColor whiteColor]]) {
        return @"White";
    }

    if ([color isEqual:[UIColor colorWithPatternImage:[UIImage imageNamed:@"camo"]]]) {
        return @"Camo";
    }
    ...
}

这只是一件疯狂的事情吗?我想我可以制作自己的具有颜色属性和颜色名称属性的对象...

【问题讨论】:

  • UIColor 的相等性(从模式或 RGB 创建)没有明确定义。通常,没有理由比较颜色。如果你需要比较颜色,那你就做错了。
  • @Sulthan 我在单元测试时会测试颜色。

标签: ios uicolor


【解决方案1】:

使用私有 API

这对CoreGraphics 进行了一些逆向工程,但我能够找到一个私有方法_CGPatternGetImage,它似乎返回了图像。

您需要包含以下标题:

#include <dlfcn.h>
@import CoreGraphics;

创建函数指针:

typedef CGImageRef (*CGPatternGetImage)(CGPatternRef pattern);

然后访问函数:

-(void)comparePatterns
{
    void *handle = dlopen("/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics", RTLD_NOW);
    CGPatternGetImage getImage = (CGPatternGetImage) dlsym(handle, "CGPatternGetImage");

    UIColor *aColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"pattern1"]];
    UIColor *bColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"pattern1"]];
    UIColor *cColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"pattern2"]];

    NSData *aImageData = UIImagePNGRepresentation([UIImage imageWithCGImage:getImage(CGColorGetPattern(aColor.CGColor))]);
    NSData *bImageData = UIImagePNGRepresentation([UIImage imageWithCGImage:getImage(CGColorGetPattern(bColor.CGColor))]);
    NSData *cImageData = UIImagePNGRepresentation([UIImage imageWithCGImage:getImage(CGColorGetPattern(cColor.CGColor))]);

    NSLog(@"Should be true: %d",[aImageData isEqual:bImageData]);
    NSLog(@"Should be false: %d",[aImageData isEqual:cImageData]);
}

您可能不想在生产应用中访问任何私有 API,但这可能对测试有用。

使用关联引用

如果这在 App Store 上进行,那么更好的解决方案可能是为 UIColor 创建一个类别,并为其提供关联引用以存储模式名称或任何最容易比较的内容。这根本不会比较实际图像,因此如果您没有设置正确的数据来识别模式,则比较可能会不准确。

包括标题:

#import <objc/runtime.h>

创建类别:

@interface UIColor(CustomPatterns)
@property (strong, nonatomic) NSString* patternName;
@end

@implementation UIColor(CustomPatterns)

static char CUSTOM_PATTERNS_PATTERN_NAME_KEY;

@dynamic patternName;

-(void)setPatternName:(NSString *)patternName
{
   objc_setAssociatedObject(self, &CUSTOM_PATTERNS_PATTERN_NAME_KEY, patternName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSString *)patternName
{
    return  (NSString*)objc_getAssociatedObject(self, &CUSTOM_PATTERNS_PATTERN_NAME_KEY);
}

@end

然后您可以设置自定义数据并进行比较:

-(void)comparePatterns
{
        UIColor *aColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"1"]];
        aColor.patternName = @"1";

        UIColor *bColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"1"]];
        bColor.patternName = @"1";

        UIColor *cColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"2"]];
        cColor.patternName = @"2";

        NSLog(@"Should be true: %d",[aColor.patternName isEqualToString:bColor.patternName]);
        NSLog(@"Should be false: %d",[aColor.patternName isEqualToString:cColor.patternName]);
}

【讨论】:

    猜你喜欢
    • 2011-11-28
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多