2010-11-26 2 views
4

Я некоторый код, который я не могу понять, почему это не работает,Сравнение UIColors

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: Но это Ждут» t, и я накормил, что один lastColor.CGColor;

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

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

ответ

6

gist.github.com/mtabini/716917

Ссылка выше работает как шарм , Спасибо ужасно «Count Chocula» и вкусный источник шоколада и ответов на iphone: P

Я бы нажал на ответ на ваш пост, но это было бы более похоже на то, что любой человек задается вопросом здесь.

Должно быть, только что был допуском поплавка.

0

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

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

Да, это особый красный цвет не по умолчанию redColor, так, например, + (UIColor *) colorWithRed: (CGFloat) красный зеленый: (CGFloat) зеленый синий: (CGFloat) синий альфа: (CGFloat) альфа; Im печатает значения, и они оба точно такие же ... точно ... но isEqual просто игнорирует этот факт. – Woodmister1

+1

Это странно. Это работает для меня: \t UIColor * aColor = [UIColor colorWithRed: 1.0 green: 0.0 blue: 0.0 alpha: 1.0]; \t NSLog (@ "% d", [aColor isEqual: [UIColor redColor]]); Если цвета имеют точно такие же компоненты, -isEqual должен работать без проблем. Вы проверили * все * компоненты, включая альфа? –

+0

Да, но я не сравниваю с redColor, если я делаю то, что вы говорите, если ([color isEqual: [UIColor red]]) Я получаю [*** Terminating app из-за неперехваченного исключения «NSInvalidArgumentException», причина: «+ [UIColor redC]: непризнанный селектор, отправленный в класс] – Woodmister1

0

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

Im, сравнивая цвет пикселя при касании и передавая его в viewcontroller, отобразит соответствующую страницу. – Woodmister1

1

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

+0

Не уверенный быть честным, получил его с этого веб-сайта на поезде, поэтому не могу проследить через него ATM его довольно низкий уровень, если я вспомню. – Woodmister1

+0

ОК, ссылка не отображается, но я уверен, что если вы получаете пиксельные цвета из UIImage, то вы читаете копию этого изображения, перемещенного в контекст, основанный на цвете RGB. Сравнение uint8_t будет гораздо менее запутанным, так как вы избегаете проблем с поплавковым сравнением –

2

Ниже приведена Быстрая версия принятого ответа. Я отбросил сравнение 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 
} 
Смежные вопросы