3

This is my NSLocalizedString:

 "YOUR_INFO" = "%i is the first number,  %i the second and %i the third";

Later on, i'm using this string like this:

 NSString *detailString = [NSString stringWithFormat:NSLocalizedString(@"YOUR_INFO", nil), firstVal, secondVal, thirdVal];

I'm trying to find out the indexes of the variables in order to use NSMutableAttributedString to highlight them in bold.

I was going to use rangeOfString, but then I realised there could be an issue if some if two values are the same.... Is there any way to get the position in the string of those variables in any other smart way?

NSGod
  • 22,699
  • 3
  • 58
  • 66
Sr.Richie
  • 5,680
  • 5
  • 38
  • 62
  • This specific string or in general? – Wain Mar 10 '14 at 19:45
  • Before replacing the control strings, bold the items. – Midhun MP Mar 10 '14 at 19:46
  • @Wain in general, as the string is localised the indexes can change – Sr.Richie Mar 10 '14 at 19:47
  • @MidhunMP mmmmmmmhhh, what do you mean exactly? – Sr.Richie Mar 10 '14 at 19:48
  • 1
    I guess the important bit is, are you always bolding all of the numbers in a string? Or arbitrary contents. If arbitrary, will the variable values exist elsewhere in the string? – Wain Mar 10 '14 at 19:48
  • @Wain this is a good point. All the ints should be bolded – Sr.Richie Mar 10 '14 at 19:50
  • @Sr.Richie: means bold the firstVal, secondVal, thirdVal and pass the bolded strings to `NSString *detailString = [NSString stringWithFormat:NSLocalizedString(@"YOUR_INFO, nil), firstVal, secondVal, thirdVal];` I don't know whether it work or not – Midhun MP Mar 10 '14 at 19:50
  • @MidhunMP, that prevents the person who localises the app from specifying the number format. Not sure how much of an issue that is... – Wain Mar 10 '14 at 19:51
  • @MidhunMP I'm just a bit confused about the concept of bolding an NSString. But my fault, I'm still a obj-c beginner.... – Sr.Richie Mar 10 '14 at 19:55
  • @Sr.Richie: Check the NSMutableAttributedString, it'll help you – Midhun MP Mar 10 '14 at 19:56

4 Answers4

1

If you just want to bold each number in a string, you could look at using enumerateSubstringsInRange:options:usingBlock: to enumerate each word in the string and check if it's numeric (longLongValue). When you find numeric values the enumeration block provides you with the range so you know what to modify in your attributed string.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • this sounds like a good idea, just a bit overkilling for my skills :( I'm now having look at @KenThomases answer here: http://stackoverflow.com/questions/11171051/call-a-method-on-every-word-in-nsstring because it's implementing what I think you're suggesting me – Sr.Richie Mar 10 '14 at 20:09
  • I'm still working on it :) successfully replaced the int with a placeholder string by using the enumerator block you were suggesting, but how to replace the ints with a NSMutableAttributedString? The problem is that the replaceCharactersInRange:withString method accepts a NSString, not a NSMutableAttributedString – Sr.Richie Mar 11 '14 at 10:51
  • Ok, you need to split. Create a mutable attributed string from the full string. Then enumerate the full string and use the range to set attributes in the attributed string (`addAttributes:range:`). You don't add attributed strings to non-attributed strings. – Wain Mar 11 '14 at 11:00
  • Yeah, you're completely right, I did it meanwhile :) – Sr.Richie Mar 11 '14 at 11:08
  • Thanks a lot for your support! I would like to offer you a redeem code of the app if you're interested in having a look :) – Sr.Richie Mar 11 '14 at 11:10
  • Sure. Maybe share it in a chat when you make your release? – Wain Mar 11 '14 at 11:19
  • Sure thing! The app is already on the store, but I'm currently working on an update. The first version I submitted was at a very early stage, so I would like you to see the new one :). By the way, do you happen to know if an app can be updated later if downloaded with a redeem code generated for a previous version? – Sr.Richie Mar 11 '14 at 11:28
  • I assume so, but I don't know (I haven't ever tried). – Wain Mar 11 '14 at 11:29
1

Use positional specifiers (... %1$i is the first number, %2$i is the second...). You need to do this anyway, with a localized string, since the order of replacement may change.

The other option is to surround the to-be-bolded values with some sentinel pattern like $>$...$<$ (being sure, of course, to post-process the string to remove the sentinels, even if no bolding is performed).

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • thx, but this then move the problem on how to access the position of the positional specifiers.... – Sr.Richie Mar 10 '14 at 20:25
  • @Sr.Richie - But you can reasonably assume that the pattern `%n$` represents a specifier, and you can determine the parm number from `n`, even if the order is changed. – Hot Licks Mar 10 '14 at 20:32
0

Try below code to get location of particular text/number in a string.. I dont know it will work for you or not..But use as per your requirement.

    NSString *notiStr;
    int location;
    int length;

    if ([detailString rangeOfString:@"1"].location == NSNotFound)
    {

    }
    else
    {
        location = [notificationString rangeOfString:@"1"].location;
        notiStr = @"1";
        length = 1;
    }
    UIFont *boldFont = [UIFont fontWithName:@"Helvitica-Bold" size:16];
    UIFont *regularFont = [UIFont fontWithName:@"Helvitica-Regular" size:16];
    NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
                                   regularFont, NSFontAttributeName,nil];


    NSDictionary *subAttrs = [NSDictionary dictionaryWithObjectsAndKeys:
                                      boldFont, NSFontAttributeName, nil];

    const NSRange range = NSMakeRange(location,length);

    NSMutableAttributedString *attributedText;

    attributedText = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@",detailedString] attributes:attrs];

    [attributedText setAttributes:subAttrs range:range];

Hope it helps you..to get an idea.

Sr.Richie
  • 5,680
  • 5
  • 38
  • 62
Vidhyanand
  • 993
  • 10
  • 21
0

Nice question!

I think, somehow, you would end-up writing your own stringWithFormat version, in other words, parsing your localized string.

You could search backwards for all %i matches in your string and apply the bold attribute. And then use replaceCharactersInRange to replace the value manually with the string representation of each number. Searching backwards could be important, depending on how you do it, because replacing a string would shift the next values.

  • (void)replaceCharactersInRange:(NSRange)aRange withString:(NSString *)aString

The new characters inherit the attributes of the first replaced character from aRange. Where the length of aRange is 0, the new characters inherit the attributes of the character preceding aRange if it has any, otherwise of the character following aRange.

Merlevede
  • 8,140
  • 1
  • 24
  • 39