Eslam Hamdy
Eslam Hamdy

Reputation: 7396

NSMutableAttributedString with NSRange issue

I have the following string

22\nShaʻban\n1435

and i'm using NSMutableAttributedString to format the above string using multiple fonts as follows:

NSString* orgString=@"22\nShaʻban\n1435";
NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:[dateStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
UIFont *dayFont=[UIFont fontWithName:@"Helvetica-Bold" size:40.0f];
UIFont *monthFont=[UIFont fontWithName:@"Arial" size:22.0f];
UIFont *yearFont=[UIFont fontWithName:@"Arial" size:20.0f];

//format day part
[attString addAttribute:NSFontAttributeName value:dayFont range:NSMakeRange(0,2)];
//format month part
[attString addAttribute:NSFontAttributeName value:monthFont range:NSMakeRange(3,[self indexOf:[dateStr substringFromIndex:3] andSearchChar:@"\n"])];
//format year part, app crashes here
[attString addAttribute:NSFontAttributeName value:yearFont range:NSMakeRange([self indexOf:[dateStr substringFromIndex:3] andSearchChar:@"\n"]+1,[dateStr length])];


- (int) indexOf:(NSString*)orgStr andSearchChar:(NSString *)charToSearc  {
NSRange range = [orgStr rangeOfString:charToSearc];
if ( range.length > 0 ) {
    return range.location;
} else {
    return -1;
  }
}

i don't know why it crashes when trying to format the last part, i made arrange from the last position in part two +1 to the length of the string, any help please

Upvotes: 0

Views: 1469

Answers (2)

Larme
Larme

Reputation: 26096

I'd suggest this:

NSString* orgString=@"22\nShaʻban\n1435";

NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] init];

UIFont *dayFont = [UIFont fontWithName:@"Helvetica-Bold" size:40.0f];
UIFont *monthFont = [UIFont fontWithName:@"Arial" size:22.0f];
UIFont *yearFont = [UIFont fontWithName:@"Arial" size:20.0f];

NSArray *array = [orgString componentsSeparatedByString:@"\n"];

[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:[array objectAtIndex:0] attributes:@{NSFontAttributeName: dayFont}]];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:[array objectAtIndex:1] attributes:@{NSFontAttributeName: monthFont}]];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
[attrString appendAttributedString:[[NSAttributedString alloc] initWithString:[array objectAtIndex:2] attributes:@{NSFontAttributeName: yearFont}]];

So, no NSRange issue. Plus as said by @Wain, you misunderstood what's a NSRange. Instead of what you're doing, once you found the location, you had to put, as second parameter of NSMakeRange: nextLocation-currentLocation. Id est, for last one, something like this:

NSMakeRange([self indexOf:[dateStr substringFromIndex:3] andSearchChar:@"\n"]+1,
            [dateStr length]-[self indexOf:[dateStr substringFromIndex:3] andSearchChar:@"\n"]+1)

Upvotes: 0

Wain
Wain

Reputation: 119041

NSRange NSMakeRange (
   NSUInteger loc,
   NSUInteger len
);

A range is a location and a length, not a start and end location. So you need to change how you calculate the range content.

Or, split the source string apart, create an attributed string for each part and then append them together.

Upvotes: 3

Related Questions