2

我有一个充满 NSString 的数组,我需要使用 NSString 来更改属性文本的颜色。我将原始 NSString 分隔成一个数组,其中包含带有颜色的单个 NSString,但我被困在这里。数组中的字符串是 [UIColor orangecolor]。我已经尝试过了,但它返回 null。

 SEL blackSel = NSSelectorFromString(@"blackColor");
 UIColor* tColor = nil;
if ([UIColor respondsToSelector: blackSel])
  tColor  = [UIColor performSelector:blackSel];
4

5 回答 5

9

I wrote a custom NSValueTransformer to allow me to translate NSColor to NSString (and back) for storage into NSUserDefaults as I didn't like the colours being stored using a byte array, which is the default behaviour. It also works across KVO, if you set the custom-transformer within IB. You can of course invoke the static methods in code to perform the transformation as well.

It shouldn't be a lot of work to rework this for UIColor:

StringColourTransformer.h:

#import <Cocoa/Cocoa.h>

@interface StringColourTransformer : NSValueTransformer

+ (NSString *)toString:(NSColor *)value;
+ (NSColor *)fromString:(NSString *)value;

@end

StringColourTransformer.m:

#import "StringColourTransformer.h"

@implementation StringColourTransformer

+ (NSString *)toString:(NSColor *)value
{
    StringColourTransformer *transformer = [[StringColourTransformer alloc] init];
    NSString *str = [transformer reverseTransformedValue:value];
    return str;
}

+ (NSColor *)fromString:(NSString *)value
{
    StringColourTransformer *transformer = [[StringColourTransformer alloc] init];
    NSColor *color = (NSColor *)[transformer transformedValue:value];
    return color;
}

+ (Class)transformedValueClass
{
    return [NSString class];
}

+ (BOOL)allowReverseTransformation
{
    return YES;
}

- (id)transformedValue:(id)value
{
    CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;

    // Only NSString classes are reverse-transformed
    if ([value isKindOfClass:[NSString class]])
    {
        NSString *stringValue = (NSString *)value;
        sscanf([stringValue UTF8String],
#ifdef __x86_64
               "%lf %lf %lf %lf",
#else
               "%f %f %f %f",
#endif
               &r, &g, &b, &a);
    }

    return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:a];
}

- (id)reverseTransformedValue:(id)value
{
    CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;

    // Only NSColor classes are transformed
    if ([value isKindOfClass:[NSColor class]])
    {
        NSColor *colourValue = (NSColor *)value;
        NSColor *converted = [colourValue colorUsingColorSpaceName:@"NSCalibratedRGBColorSpace"];
        [converted getRed:&r green:&g blue:&b alpha:&a];
    }

    return [NSString stringWithFormat:@"%.3f %.3f %.3f %.3f", r, g, b, a];
}

@end
于 2013-06-15T08:40:29.127 回答
4

Use this method,Will convert colorname to the object UIColor

-(UIColor *)giveColorfromStringColor:(NSString *)colorname
{
    SEL labelColor = NSSelectorFromString(colorname);
    UIColor *color = [UIColor performSelector:labelColor];
    return color;
}
于 2013-06-15T08:36:19.340 回答
2

您可以简单地将这种格式 @"1 0.96 0.75 1" 用于您的字符串,其中值是红色、绿色、蓝色和 alpha。然后使用 CIColor 将它们转换为 UIColor!

这是一个例子:

      NSString *spinnerColorStr = @"1 0.96 0.75 1";
      CIColor *spinnerCi = [CIColor colorWithString:spinnerColorStr];
      UIColor *spinnerColor = [UIColor colorWithRed:spinnerCi.red green:spinnerCi.green blue:spinnerCi.blue alpha:spinnerCi.alpha];
于 2014-02-06T14:06:26.720 回答
1

基于@trojanfoe 的出色回答,我制作了一个基于类别的解决方案,我用它来从他们的 Info.plist 文件中动态配置 UIViewControllers(当您有许多应用程序共享一个公共代码库时会有所帮助):

UIColor+String.h:

#import <UIKit/UIKit.h>

@interface UIColor (String)

+(UIColor*) colorFromString:(NSString*) string;

@end

UIColor+String.m:

#import "UIColor+String.h"

@implementation UIColor (String)

/**
 c.f. http://stackoverflow.com/a/17121747/153422
 */
+(UIColor *)colorFromString:(NSString *)stringValue
{
    CGFloat r = 0.0, g = 0.0, b = 0.0, a = 1.0;
    sscanf([stringValue UTF8String],
#ifdef __x86_64
           "%lf %lf %lf %lf",
#else
           "%f %f %f %f",
#endif
           &r, &g, &b, &a);

    return [UIColor colorWithRed:r green:g blue:b alpha:a];
}

@end

使用示例:

NSString* colourString = [[NSBundle mainBundle].infoDictionary valueForKeyPath:@"Theme.Colours.NavigationBar.Title"];
    lTitle.textColor = [UIColor colorFromString:colourString];

(这假设你编辑了你的 Info.plist 并添加了一个带有 subdict “Colours”的 Dict “Theme”,一个 subdict “NavigationBar”,一个 NSString “Title”,其值为例如“1 0 0 1”(红色))

于 2013-11-20T16:31:06.560 回答
0

[Look for edit below]

I would use a lookup table. In this case a dictionary that will hold the possible values as key's and the values as UIColor objects. Such as :

NSDictionary *colorTable = @{
    @"blackColor" : [UIColor blackColor],
    @"greenColor" : [UIColor greenColor],
    @"redColor" : [UIColor redColor]
};

So that way when you want to "convert" a color string, you would :

UIColor *myConvertedColor = [colorTable objectWithKey:@"blackColor"];

myConvertedColor will be a UIColorBlack.

Hope this helps! Good Luck!


--->>EDIT<<----

Ok, here's tested code. Try it somewhere clean so that you won't get interference from other things that might be running. Note that I am asuming iOS.. Otherwise change UIColor for NSColor..

  NSDictionary *colorTable = @{
                                 @"blackColor" : [UIColor blackColor],
                                 @"greenColor" : [UIColor greenColor],
                                 @"redColor" : [UIColor redColor]
                                 };


    UIColor *myConvertedColorNull = [colorTable objectForKey:@"whiteColor"]; //NULL
    UIColor *myConvertedColor = [colorTable objectForKey:@"blackColor"]; //NOT NULL

    NSLog(@"MyColor: %@", [myConvertedColor description]);
    NSLog(@"MyColorNULL: %@", [myConvertedColorNull description]);

This produces this output:

MyColor: UIDeviceWhiteColorSpace 0 1 MyColorNULL: (null)

As you can see, the MyColorNULL is to prove how you should not do the search, while the other proves that my code works.

if it helps, please tag my answer as correct. If it doesn't let's keep working it out.

于 2013-06-15T08:36:31.203 回答