Сравнение UIColors - PullRequest
       3

Сравнение UIColors

4 голосов
/ 26 ноября 2010

У меня есть код, который я не могу понять, почему он не работает,

UIColor *lastColor, *red;
red = [UIColor colorWithRed:0.993 green:0.34444 blue:0.0 alpha:1.0]; 

NSString *chosenColor;

if([lastColor isEqual: red])
{
   chosenColor = @"red";
}

Я также обнаружил, что некоторые люди делают переопределение метода isEqual, isEqualtoColor: Но это тоже не сработало, и я накормил этот lastColor.CGColor;

Везде, где я читал, isEqual - это все, что вам нужно для сравнения UIColors, в настоящее время я прибегаю к массиву строк для красного, зеленого и синего и сравниваю значение с плавающей точкой с CGColorGetComponents (lastColor);

Но это тоже не работает.

Ответы [ 5 ]

6 голосов
/ 28 ноября 2010

gist.github.com / mtabini / 716917

Ссылка выше работает как шарм. Огромное спасибо "Графу Чокуле" и восхитительному источнику шоколада, и ответы на iPhone: P

Я бы нажал кнопку "Ответить" на ваше сообщение, но это, скорее всего, приведет в замешательство всех, кому интересно здесь.

Должно быть, это просто допуск.

2 голосов
/ 18 февраля 2016

Вот Swift-версия принятого ответа.Я отбросил сравнение CGColorSpaceRef, так как не смог найти простой способ сделать это быстро, но, похоже, это не повлияет на результаты, кроме как с точки зрения производительности.

class func colorsConsideredSimilar(color: UIColor, otherColor: UIColor) -> Bool {
    let tolerance: CGFloat = 0.05 // 5%

    let colorRef: CGColorRef = color.CGColor
    let otherColorRef: CGColorRef = otherColor.CGColor

    let componentCount = CGColorGetNumberOfComponents(colorRef)

    let components = CGColorGetComponents(colorRef)
    let otherComponents = CGColorGetComponents(otherColorRef)

    for var i = 0; i < componentCount; i++ {
        let difference = components[i] / otherComponents[i]

        if (fabs(difference - 1) > tolerance) {
            return false
        }
    }

    return true
}
1 голос
/ 26 ноября 2010

Если вы выбираете цвет пикселя из CGContext с цветовым пространством RGB, он может не совпадать с тем, который используется классом UIColor. Значения пикселей в прямых ссылках на память в CGContext будут 0-255 (в RGB). В зависимости от палитры цветов, с которыми вы хотите сравнить, я, вероятно, подхожу к этому, используя значения uint8_t, чтобы избежать смещения и выполнять обобщенные сравнения на основе доминирующих значений в RGB

0 голосов
/ 26 ноября 2010

-[UIColor isEqual:] - это встроенный способ сравнения цветов.Тем не менее, вы должны помнить, что хотя два цвета могут казаться одинаковыми для ваших глаз на конкретном устройстве, они могут различаться математически и поэтому сравниваются неравно.Два цвета, которые кажутся вашим глазам разными (например, «чистый красный» в RGB и «чистый красный» в CMYK), при преобразовании в нейтральное цветовое пространство для сравнения могут сравниваться равными.

Цветовые пространстваb_ _ вот так.:)

Если вы сообщите нам почему вы хотите сравнить два цвета, мы можем предложить вам лучшее решение, чем прямое сравнение.

В ответна ваш комментарий: Не основывайте тестирование попаданий вашего пользовательского интерфейса на цвете отдельных или даже нескольких пикселей.Их абсолютные значения могут изменяться в зависимости от цветового пространства устройства, что приводит к ложным и отрицательным результатам.Скорее, вы можете определить области «горячей точки», разместив невидимые UIButton объекты в вашем интерфейсе, или, что еще лучше, используя что-то более гибкое, например CGPath, и проверьте, попадает ли касание в его границы.Может работать что-то вроде следующего:

@interface HotSpottyView : UIView {
    @private NSMutableDictionary *hotspots;
}
- (void)addHotspot: (CGPathRef)path withBlock: (void (^ handler)(void));
@end


@implementation HotSpottyView
- (id)initWithFrame: (CGRect)frameRect {
    self = [super initWithFrame: frameRect];

    if (self) {
        self->hotspots = [[NSMutableDictionary alloc] init];
    }

    return self;
}

- (id)initWithCoder: (NSCoder *)aDecoder {
    self = [super initWithFrame: frameRect];

    if (self) {
        self->hotspots = [[NSMutableDictionary alloc] init];
    }

    return self;
}

- (void)dealloc {
    [self->hotspots release];
    [super dealloc];
}

- (void)addHotspot: (CGPathRef)path withBlock: (void (^ handler)(void)) {
    CGPathRef immutablePath = CGPathCreateCopy(path);
    if (immutablePath) {
        [self->hotspots setObject: handler forKey: (id)immutablePath];
        CGPathRelease(immutablePath);
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *t = [touches anyObject];
    CGPoint loc = [t locationInView: self];
    if (CGRectContainsPoint(self.bounds, loc)) {
        for (id path in self->hotspots) {
            if (CGPathContainsPoint((CGPathRef)path, NULL, loc, FALSE)) {
                void (^ handler)(void) = [self->hotspots objectForKey: path];
                handler();
            }
        }
    }
}
@end
0 голосов
/ 26 ноября 2010

Вы на самом деле инициализируете красную переменную? Это должно работать:

if ([lastColor isEqual:[UIColor redColor]]) {
  /* … */
}
...