Get CGRect from NSStringFromCGRect - objective-c

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"];

Related

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)

Annotations on MapView: Coordinates

I have two NSStrings (address, and key) which contain the coordinates (longitude and latitude) in form of numbers (34,56789...):
NSString *key = [allKeys objectAtIndex:i];
NSObject *obj = [DictionaryMap objectForKey:key];
NSString *address = [NSString stringWithFormat:#"%#", obj];
CLLocationCoordinate2D anyLocation;
anyLocation.latitude = [address doubleValue];
anyLocation.longitude = [key doubleValue];
MKPointAnnotation *annotationPoint2 = [[MKPointAnnotation alloc] init]; annotationPoint2.coordinate = anyLocation;
annotationPoint2.title = #"Event";
annotationPoint2.subtitle = #"Microsoft's headquarters2";
[mapView addAnnotation:annotationPoint2];
...But I can't understand why it doesn't plot in the same point as the coordinates written. I think this doesn't work:
[address doubleValue]
So I tried replacing it with:
location.latitude = NSNumber/NSString
but it gives an error.
UPDATE:
IN VIEW DID LOAD:
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressGesture:)];
[self.mapView addGestureRecognizer:longPressGesture];
[mapView.userLocation setTitle:#"I am here"];
..then...
-(void)handleLongPressGesture:(UIGestureRecognizer*)sender {
// This is important if you only want to receive one tap and hold event
if (sender.state == UIGestureRecognizerStateEnded)
{
[self.mapView removeGestureRecognizer:sender];
}
else
{
// Here we get the CGPoint for the touch and convert it to latitude and longitude coordinates to display on the map
CGPoint point = [sender locationInView:self.mapView];
CLLocationCoordinate2D locCoord = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
// Then all you have to do is create the annotation and add it to the map
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init]; annotationPoint.coordinate = locCoord;
annotationPoint.title = #"Microsoft";
annotationPoint.subtitle = #"Microsoft's headquarters";
[mapView addAnnotation:annotationPoint];
NSString *latitude = [[NSString alloc] initWithFormat:#"%f",locCoord.latitude];
NSString *longitude = [[NSString alloc] initWithFormat:#"%f", locCoord.longitude];
NSLog(latitude);
NSLog(longitude);
[[NSUserDefaults standardUserDefaults]setObject:latitude forKey:#"FolderLatitude"];
[[NSUserDefaults standardUserDefaults]setObject:longitude forKey:#"FolderLongitude"];
}
}
...I then save the coordinates in a JSON file and then read them from the file.
Print out the values that you are setting for lat/lon. It sounds like these values are not being converted to double properly. If the strings are not in "xxx.xxx" format then they will not convert to doubles properly when you call doubleValue.
Finally I understood: This is the correct way to make it work:
NSString *myString = (string initialization here)
float stringFloat = [myString floatValue];
anyLocation.longitude = stringFloat;

Adding Annotations for coordinates MKMapView

I am parsing this JSON file (correctly, it works with the UITextFields):
{"longitude":["37.786793","39.388528"],"latitude":["-122.395416","-78.887734"]}
ind creating MapViews, with the respective annotations in this way:
NSArray *allKeys2 = [DictionaryMap allKeys];
for (int h = 0; h < [allKeys2 count]; h++) {
CGRect mapFrame = CGRectMake( 400, e, 200, 110);
MKMapView *mapView2 = [[MKMapView alloc] initWithFrame:mapFrame];
[image1 addSubview:mapView2];
NSString *key2 = [allKeys2 objectAtIndex:i];
NSObject *obj2 = [DictionaryMap objectForKey:key2];
NSString *address = [NSString stringWithFormat:#"%#", obj2];
float stringFloat = [address floatValue];
float stringFloat2 = [key2 floatValue];
CLLocationCoordinate2D anyLocation;
anyLocation.longitude = stringFloat;
anyLocation.latitude = stringFloat2;
MKPointAnnotation *annotationPoint2 = [[MKPointAnnotation alloc] init]; annotationPoint2.coordinate = anyLocation;
annotationPoint2.title = #"Event";
annotationPoint2.subtitle = #"Microsoft's headquarters2";
[mapView2 addAnnotation:annotationPoint2];
[mapView2.userLocation setTitle:#"I am here"];
[mapView2.userLocation addObserver:self
forKeyPath:#"location"
options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
context:NULL];
[mapView2 setShowsUserLocation:NO];
[MapViewArray addObject:mapView2];
if (MapViewArray == nil)MapViewArray = [[NSMutableArray alloc]init];
[MapViewArray addObject: mapView2];
}}
}while(g < f);
...I want the first map view to show the first coordinate pin, and the second to show the second pair of coordinates. But now, it is plotting on all the map views the same pin, corresponding to the last coordinates, and not to the first and second... respectively. This method works for the UITextField text, so I can't find the problem.
Please help!!
EDIT:
NSString *filenameMap = [NSString stringWithFormat:#"%#%#Map", destDir, NavBar.topItem.title];
NSString *MapPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#Map", NavBar.topItem.title]];
[self.restClient loadFile:filenameMap intoPath:MapPath];
NSString *fileContentMap = [[NSString alloc] initWithContentsOfFile:MapPath];
SBJsonParser *parserMap = [[SBJsonParser alloc] init];
NSDictionary *dataMap = (NSDictionary *) [parserMap objectWithString:fileContentMap error:nil];
NSArray *MaparrayLongitude = [dataMap objectForKey:#"longitude"];
NSArray *MaparrayLatitude = [dataMap objectForKey:#"latitude"];
NSDictionary* DictionaryMap = [NSDictionary dictionaryWithObjects:MaparrayLatitude forKeys:MaparrayLongitude];
Another take:
You probably don't want to map your latitudes to longitudes in DictionaryMap. How about making an NSArray of NSDictionaries, where each dictionary has a "latitude" key and a "longitude" key?
Also, you have "[MapViewArray addObject: mapView2]" twice in your code.
And what is "g"? Maybe add some logging to your loop so you can see what's being created?

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.

Store and get UIColor from .plist file

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 );