Search code examples
objective-ccocoa-touchnsattributedstringnsrange

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


Solution

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