Store and get UIColor from .plist file - objective-c

I've been searching for this for a while now with no success. My question is: is there an easy way to store and get UIColors such as [UIColor blackColor] or [UIColor colorWithRed:0.38 green:0.757 blue:1 alpha:1]; in a .plist file in my app directory?

according to this discussion you have two options:
Store it like NSData in Data field of .plist file
Store it like String UIColor representation
NSData option
NSData *theData = [NSKeyedArchiver archivedDataWithRootObject:[UIColor greenColor]];
NSString option
NSString *color = #"greenColor";
[UIColor performSelector:NSSelectorFromString(color)]
read more here: http://www.iphonedevsdk.com/forum/iphone-sdk-development/27335-setting-uicolor-plist.html

If you want to keep it human readabe,
I did a category for this:
#implementation UIColor (EPPZRepresenter)
NSString *NSStringFromUIColor(UIColor *color)
{
const CGFloat *components = CGColorGetComponents(color.CGColor);
return [NSString stringWithFormat:#"[%f, %f, %f, %f]",
components[0],
components[1],
components[2],
components[3]];
}
UIColor *UIColorFromNSString(NSString *string)
{
NSString *componentsString = [[string stringByReplacingOccurrencesOfString:#"[" withString:#""] stringByReplacingOccurrencesOfString:#"]" withString:#""];
NSArray *components = [componentsString componentsSeparatedByString:#", "];
return [UIColor colorWithRed:[(NSString*)components[0] floatValue]
green:[(NSString*)components[1] floatValue]
blue:[(NSString*)components[2] floatValue]
alpha:[(NSString*)components[3] floatValue]];
}
#end
The same formatting that is used by NSStringFromCGAffineTransform. This is actually a part of a bigger scale plist object representer in [eppz!kit at GitHub][1].

The best and readable way in Objective-c is to save it as hex string like: "#1A93A8", then to get it by extern method;
in .h file:
extern UIColor *colorFromHEX(NSString *hex);
extern NSString *HEXFromColor(UIColor *color);
in .m file:
UIColor *colorFromHEX(NSString *hex){
NSString *stringColor = hex;
int red, green, blue;
sscanf([stringColor UTF8String], "#%02X%02X%02X", &red, &green, &blue);
UIColor *color = [UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:1];
return color;
}
NSString *HEXFromColor(UIColor *color){
const CGFloat *components = CGColorGetComponents(color.CGColor);
size_t count = CGColorGetNumberOfComponents(color.CGColor);
if(count == 2){
return [NSString stringWithFormat:#"#%02lX%02lX%02lX",
lroundf(components[0] * 255.0),
lroundf(components[0] * 255.0),
lroundf(components[0] * 255.0)];
}else{
return [NSString stringWithFormat:#"#%02lX%02lX%02lX",
lroundf(components[0] * 255.0),
lroundf(components[1] * 255.0),
lroundf(components[2] * 255.0)];
}
}
in any where
NSDictionary *Config = [[NSDictionary alloc] initWithContentsOfFile:[NSBundle.mainBundle pathForResource:#"Config" ofType:#"plist"]];
UIColor *color = colorFromHEX( Config[#"color"] );
NSString *strColor = HEXFromColor( UIColor.blackColor );

Related

Get CGRect from NSStringFromCGRect

I stored a frame (CGRect) in a NSStringFromCGRect, how do I later retrieve the rect?
[mDict setObject:NSStringFromCGRect(frame) forKey:#"frame"];
I need to get the data back how?
CGRect frame = [[mDict objectForKey:#"frame"] ..?]
Does a method exist or I have to parse the string manually?
I think you are looking for,
CGRect frame = CGRectFromString([mDict objectForKey:#"frame"]);
I recommend to use NSValue instead of creating a string representation.
NSValue instances are objects and can be put into a dictionary
CGRect frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
NSValue *value = [NSValue valueWithRect:(NSRect)frame];
NSDictionary *dict = #{#"frame" : value};
CGRect frameBack = (CGRect)[dict[#"frame"] rectValue];
NSLog(#"%#", NSStringFromRect(frameBack));
If you need a string representation which is easily reversible, you could use this
CGRect frame = CGRectMake(0.0, 0.0, 100., 100.0);
NSValue *value = [NSValue valueWithRect:(NSRect)frame];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
NSString *base64String = [data base64EncodedStringWithOptions:0];
NSLog(#"%#", base64String);
NSData *dataBack = [[NSData alloc] initWithBase64Encoding:base64String];
NSValue *valueBack = (NSValue *)[NSKeyedUnarchiver unarchiveObjectWithData:dataBack];
CGRect frameBack = (CGRect)[valueBack rectValue];
NSLog(#"%#", NSStringFromRect(frameBack));
Until someone find a better solution this is what I came up with:
-(CGRect) CGRectFromNStringFromCGRect: (NSString *) string {
NSString *newString = [string stringByReplacingOccurrencesOfString:#"{" withString:#""];
newString = [newString stringByReplacingOccurrencesOfString:#"}" withString:#""];
newString = [newString stringByReplacingOccurrencesOfString:#" " withString:#""];
NSArray *array = [newString componentsSeparatedByString:#","];
if ([array count]==4) {
return CGRectMake([array[0] floatValue], [array[1] floatValue], [array[2] floatValue], [array[3] floatValue]);
} else {
return CGRectZero;
}
}
Use Like this:
CGRect frame = [self CGRectFromNStringFromCGRect:[mDict objectForKey:#"frame"];

Objective C UIColor to NSString

I need to convert a UIColor to an NSString with the name of the color i.e.
[UIColor redColor];
should become
#"RedColor"
I've already tried[UIColor redColor].CIColor.stringRepresentation
but it causes a compiler error
Just expanding on the answer that #Luke linked to which creates a CGColorRef to pass to CIColor:
CGColorRef colorRef = [UIColor grayColor].CGColor;
You could instead simply pass the CGColor property of the UIColor you're working on like:
NSString *colorString = [[CIColor colorWithCGColor:[[UIColor redColor] CGColor]] stringRepresentation];
Don't forget to import the Core Image framework.
Side note, a quick and easy way to convert back to a UIColor from the string could be something like this:
NSArray *parts = [colorString componentsSeparatedByString:#" "];
UIColor *colorFromString = [UIColor colorWithRed:[parts[0] floatValue] green:[parts[1] floatValue] blue:[parts[2] floatValue] alpha:[parts[3] floatValue]];
This is the shortest way to convert UIColor to NSString:
- (NSString *)stringFromColor:(UIColor *)color
{
const size_t totalComponents = CGColorGetNumberOfComponents(color.CGColor);
const CGFloat * components = CGColorGetComponents(color.CGColor);
return [NSString stringWithFormat:#"#%02X%02X%02X",
(int)(255 * components[MIN(0,totalComponents-2)]),
(int)(255 * components[MIN(1,totalComponents-2)]),
(int)(255 * components[MIN(2,totalComponents-2)])];
}

Unable to add custom links to OHAttributeLabel

I am using OHAttributeLabel to add custom links to my label's text. The code that I am using is pasted below. It used to work with the older version of OHAttributed label (2010), however with the new version (recently updated), the text in my label are no longer clickable as links.
Can anyone advise what I am missing here?
// Set Question Label
Question *question = self._answerForCell.question;
NSString *questionText = [NSString stringWithFormat:#"Q: %#", question.text];
CustomOHAttributLabel *thisQuestionLabel = (CustomOHAttributLabel *)[self.contentView viewWithTag:QUESTIONLABEL_TAG];
//Set up dictionary for question
NSString *questionStr = [question.text stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString *urlForQn = [NSString stringWithFormat:#"dailythingsfm://redirect_to/questions/%#/answers?text=%#&nickname=%#&question_id=%#&question_curious=%i&showEveryOneTab=%i", question.slug, questionStr, [[UserInfo sharedUserInfo] getNickname], question.qid, question.curious, 1];
NSString *qnStartIndex = #"0";
NSString *qnLength = [NSString stringWithFormat:#"%i", [questionText length]];
NSDictionary *qnDict = [NSDictionary dictionaryWithObjectsAndKeys:qnStartIndex, #"start", qnLength, #"length", urlForQn, #"url", nil];
NSArray *array = [NSArray arrayWithObject:qnDict];
[thisQuestionLabel setLabelwithText:questionText fontSize:QUESTION_FONT_SIZE andSubStringToURLArrayViaRange:array withHexColor:#"#555555"];
//Method to set the text in UILabel to a custom link
- (void)setLabelwithText:(NSString *)text fontSize:(CGFloat)fontSize andSubStringToURLArrayViaRange:(NSArray *)array withHexColor:(NSString *)textColor
{
NSMutableAttributedString *attrStr = [NSMutableAttributedString attributedStringWithString:text];
[attrStr setFont:[UIFont systemFontOfSize:fontSize]];
[attrStr setTextColor:[UIColor grayColor]];
[self removeAllCustomLinks];
for (NSDictionary *dict in array) {
NSString *start = [dict objectForKey:#"start"];
NSString *length = [dict objectForKey:#"length"];
NSString *url = [dict objectForKey:#"url"];
NSUInteger startIndex = [start intValue];
NSUInteger len = [length intValue];
NSRange range = NSMakeRange(startIndex, len);
[attrStr setFont:[UIFont boldSystemFontOfSize:fontSize] range:range];
[attrStr setTextColor:[UIColor colorWithHexString:textColor] range:range];
[self addCustomLink:[NSURL URLWithString:url] inRange:range];
}
self.attributedText = attrStr;
}
I have to use 'setLink' method instead of addCustomLink for the latest OHAttribute Library (3.2.1)

Storing UIColors in NSDictionary and retrieving them?

I need to return a specific UIColor for a given index.
I am trying to basically store the UIColors as NSArrays
TypeColors = [[NSDictionary alloc] initWithObjectsAndKeys:
#"1", [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.5],[NSNumber numberWithFloat:0.5],[NSNumber
numberWithFloat:0.5],[NSNumber numberWithFloat:1.0], nil],
#"5", [NSArray arrayWithObjects:[NSNumber numberWithFloat:1.0],[NSNumber
numberWithFloat:0.5],[NSNumber numberWithFloat:0.1],[NSNumber
numberWithFloat:1.0], nil]
, nil]; //nil to signify end of objects and keys.
And here I want to retrieve the UIColor back from that dictionary:
a = 5;
NSArray* colorArray = [TypeColors objectForKey:a];
UIColor* color = [UIColor colorWithRed:[colorArray objectAtIndex:0]
green:[colorArray objectAtIndex:1] blue:[colorArray objectAtIndex:2]
alpha:[colorArray objectAtIndex:3]];
It always returns me a zero, anyone knows why?
Thanks!
Change it to
UIColor* color = [UIColor colorWithRed:[[colorArray objectAtIndex:0] floatValue]
green:[[colorArray objectAtIndex:1] floatValue] blue:[[colorArray objectAtIndex:2] floatValue]
alpha:[[colorArray objectAtIndex:3] floatValue]];
The parameter to be sent there is cgfloat and not NSNumber
Two things:
1) The order of things in initWithObjectsAndKeys are objects and then their keys. Yes, it is intuitively backwards.
2) The key is not an integer 5 but an NSString #"5".
You need to convert your UIcolor to Nsstring first before save it in dictionary as follow :
-(NSString *)convertColorToString :(UIColor *)colorname
{
if(colorname==[UIColor whiteColor] )
{
colorname= [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
}
else if(colorname==[UIColor blackColor])
{
colorname= [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
}
else
{
colorname=colorname;
}
CGColorRef colorRef = colorname.CGColor;
NSString *colorString;
colorString=[CIColor colorWithCGColor:colorRef].stringRepresentation;
return colorString;
}
and when you want to fetch the value from dictionary than you need to convert string to color as follow
-(UIColor *)convertStringToColor :(NSDictionary *)dicname :(NSString *)keyname
{
CIColor *coreColor = [CIColor colorWithString:[dicname valueForKey:keyname]];
UIColor *color = [UIColor colorWithRed:coreColor.red green:coreColor.green blue:coreColor.blue alpha:coreColor.alpha];
//NSLog(#"color name :%#",color);
return color;
}
exa :
here dicSaveAllUIupdate is my dictionary and i saved my view background color in it.
[dicSaveAllUIupdate setObject:[self convertColorToString: self.view.backgroundColor] forKey:#"MAINVW_BGCOLOR"];
and i will retrive it as follow
self.view.backgroundColor=[self convertStringToColor:retrievedDictionary:#"MAINVW_BGCOLOR"];
Hope this help to you ...

How to set the UILabel's UIColor from a Plist

the question is in the title, How to set the UILabel's UIColor from a Plist ?
i tried this :
UIColor *colorLabel;
i add a NSString row in my Plist, and wrote redColor as a value but doesnt work...
How can i handle it ?
Thanks guys.
I would personally store the RGBA values instead of a string and then you can just use
+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha
Do not do the below
Just as an interesting side note the most inflexible way would be to use the UIColor convenience methods like this
[UIColor performSelector:NSSelectorFromString(#"redColor")]
I think you need convert from string to an UIColor. You put colors into your plist by hex-colors (for red - ff0000) and then use something like following function for get UIColor.
+ (UIColor *) colorWithHexString: (NSString *) stringToConvert
{
    NSString *cString = [[stringToConvert stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
    // String should be 6 or 8 characters
    if ([cString length] < 6) return [UIColor blackColor];
    // strip 0X if it appears
    if ([cString hasPrefix:#"0X"]) cString = [cString substringFromIndex:2];
    if ([cString length] != 6) return [UIColor blackColor];
    // Separate into r, g, b substrings
    NSRange range;
    range.location = 0;
    range.length = 2;
    NSString *rString = [cString substringWithRange:range];
    range.location = 2;
    NSString *gString = [cString substringWithRange:range];
    range.location = 4;
    NSString *bString = [cString substringWithRange:range];
    // Scan values
    unsigned int r, g, b;
    [[NSScanner scannerWithString:rString] scanHexInt:&r];
    [[NSScanner scannerWithString:gString] scanHexInt:&g];
    [[NSScanner scannerWithString:bString] scanHexInt:&b];
    
    return [UIColor colorWithRed:((float) r / 255.0f)
                       green:((float) g / 255.0f)
                            blue:((float) b / 255.0f)
                       alpha:1.0f];
}
To preserve human readability, I did a category for this:
#implementation UIColor (EPPZRepresenter)
NSString *NSStringFromUIColor(UIColor *color)
{
const CGFloat *components = CGColorGetComponents(color.CGColor);
return [NSString stringWithFormat:#"[%f, %f, %f, %f]",
components[0],
components[1],
components[2],
components[3]];
}
UIColor *UIColorFromNSString(NSString *string)
{
NSString *componentsString = [[string stringByReplacingOccurrencesOfString:#"[" withString:#""] stringByReplacingOccurrencesOfString:#"]" withString:#""];
NSArray *components = [componentsString componentsSeparatedByString:#", "];
return [UIColor colorWithRed:[(NSString*)components[0] floatValue]
green:[(NSString*)components[1] floatValue]
blue:[(NSString*)components[2] floatValue]
alpha:[(NSString*)components[3] floatValue]];
}
#end
The same formatting that is used by NSStringFromCGAffineTransform. This is actually a part of a bigger scale plist object representer in eppz!kit at GitHub.