40

How can I uppercase the fisrt letter of a NSString, and removing any accents ?

For instance, Àlter, Alter, alter should become Alter.

But, /lter, )lter, :lter should remains the same, as the first character is not a letter.

Binarian
  • 12,296
  • 8
  • 53
  • 84
Nielsou Hacken-Bergen
  • 2,606
  • 6
  • 27
  • 37

7 Answers7

119

Please Do NOT use this method. Because one letter may have different count in different language. You can check dreamlax answer for that. But I'm sure that You would learn something from my answer.

NSString *capitalisedSentence = nil;

//Does the string live in memory and does it have at least one letter?
if (yourString && yourString.length > 0) {
    // Yes, it does.
    
     capitalisedSentence = [yourString stringByReplacingCharactersInRange:NSMakeRange(0,1)
                                                               withString:[[yourString substringToIndex:1] capitalizedString]];
} else {
    // No, it doesn't.
}

Why should I care about the number of letters?

If you try to access (e.g NSMakeRange, substringToIndex etc) the first character in an empty string like @"", then your app will crash. To avoid this you must verify that it exists before processing on it.

What if my string was nil?

Mr.Nil: I'm 'nil'. I can digest anything that you send to me. I won't allow your app to crash all by itself. ;)

Animation of a person swallowing fake explosives, it going off in his stomach, and then smoke coming from his mouth in a cartoonish fashion without injury.

nil will observe any method call you send to it.

So it will digest anything you try on it, nil is your friend.

starball
  • 20,030
  • 7
  • 43
  • 238
  • capitalisedString already change nothing but the first letter, so it is useless to select it. The problem is that it doesn't remove accents. Thanks – Nielsou Hacken-Bergen Sep 09 '11 at 09:28
  • 9
    capitalizedString capitalize the first letter of each word in the NSString. This answer is useful to capitalize only the first letter of a sentence. – gsempe Jul 23 '12 at 06:21
  • Downvoted. Although very simple, the solution is wrong. Imagine a situation when several letters should be capitalized instead of only the first one. A good example here is Dutch with its IJ pair. When it comes to capitalization, you should always work with locale. – Aleks N. Sep 01 '14 at 09:59
  • Downvoted as well, this doesn't fully answer the OP's question. This capitalises only the first character but does not remove diacritic marks. – dreamlax Sep 01 '14 at 11:25
  • Using a hard-coded `NSMakeRange(0,1)` is incorrect (as first letter may span multiple characters). Please see my comment in @dreamlax 's answer for a solution. – Oz Solomon Oct 06 '15 at 13:08
  • @OzSolomon I completely indeed. You were right. His answer has localization also. But I hope you might have learnt something from my answer.I have updated my answer. :) – Vijay-Apple-Dev.blogspot.com Oct 06 '15 at 13:43
  • @Vijay-Apple-Dev.blogspot.com I hope you don't mind I removed your warning about the character range and edited the code to actually take it into account. – Oz Solomon Oct 06 '15 at 18:20
  • @OzSolomon Thank you for your concern. Thumbs up:) – Vijay-Apple-Dev.blogspot.com Mar 22 '16 at 06:52
90

You can use NSString's:

- (NSString *)capitalizedString

or (iOS 6.0 and above):

- (NSString *)capitalizedStringWithLocale:(NSLocale *)locale

meaning-matters
  • 21,929
  • 10
  • 82
  • 142
55

Since you want to remove diacritic marks, you could use this method in combination with the common string manipulating methods, like this:

/* create a locale where diacritic marks are not considered important, e.g. US English */
NSLocale *locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en-US"] autorelease];

NSString *input = @"Àlter";

/* get first char */
NSString *firstChar = [input substringToIndex:1];

/* remove any diacritic mark */
NSString *folded = [firstChar stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:locale];

/* create the new string */
NSString *result = [[folded uppercaseString] stringByAppendingString:[input substringFromIndex:1]];
dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • 2
    Downvoted. Some languages, Dutch for instance, have digraphs, like IJ, and thus require capitalization of both letters: http://en.wikipedia.org/wiki/Capitalization – Aleks N. Sep 01 '14 at 10:13
  • 2
    @AliakseiN.: That wasn't specified in the original question. The OP wanted to remove diacritic marks and capitalise only the first letter, so I assumed that he/she did not want to retain any locale-specific orthography. – dreamlax Sep 01 '14 at 11:23
  • There is a small bug with this code in that it assumes that the first letter is 1 character long which is not correct for UTF strings. Instead it should call `NSString *firstChar = [input substringWithRange:[input rangeOfComposedCharacterSequenceAtIndex:0]]` and later use `[input substringFromIndex:firstChar.length]` – Oz Solomon Oct 06 '15 at 13:06
2

Since iOS 9.0 there is a method to capitalize string using current locale:

@property(readonly, copy) NSString *localizedCapitalizedString;
ASLLOP
  • 174
  • 2
  • 12
2

Gonna drop a list of steps which I think you can use to get this done. Hope you can follow through without a prob! :)

  • Use decomposedStringWithCanonicalMappingto decompose any accents (Important to make sure accented characters aren't just removed unnecessarily)
  • Use characterAtIndex: to extract the first letter (index 0), use upperCaseString to turn it into capitol lettering and use stringByReplacingCharactersInRange to replace the first letter back into the original string.
  • In this step, BEFORE turning it into uppercase, you can check whether the first letter is one of the characters you do not want to replace, e.g. ":" or ";", and if it is, do not follow through with the rest of the procedure.
  • Do a [theString stringByReplacingOccurrencesOfString:@"" withString:@""]` sort of call to remove any accents left over.

This all should both capitalize your first letter AND remove any accents :)

Madhu
  • 2,429
  • 16
  • 31
1

I'm using this method for similar situations but I'm not sure if question asked to make other letters lowercase.

- (NSString *)capitalizedOnlyFirstLetter {

    if (self.length < 1) {
        return @"";
    }
    else if (self.length == 1) {
        return [self capitalizedString];
    }
    else {

        NSString *firstChar = [self substringToIndex:1];
        NSString *otherChars = [self substringWithRange:NSMakeRange(1, self.length - 1)];

        return [NSString stringWithFormat:@"%@%@", [firstChar uppercaseString], [otherChars lowercaseString]];
    }
}
Josip B.
  • 2,434
  • 1
  • 25
  • 30
0

Just for adding some options, I use this category to capitalize the first letter of a NSString.

@interface NSString (CapitalizeFirst)
    - (NSString *)capitalizeFirst;
    - (NSString *)removeDiacritic;
@end

@implementation NSString (CapitalizeFirst)
- (NSString *)capitalizeFirst {
    if ( self.length <= 1 ) {
        return [self uppercaseString];
    }
    else {
        return [[[[self substringToIndex:1] removeDiacritic] uppercaseString] stringByAppendingString:[[self substringFromIndex:1] removeDiacritic]];
        // Or: return [NSString stringWithFormat:@"%@%@", [[[self substringToIndex:1] removeDiacritic] uppercaseString], [[self substringFromIndex:1] removeDiacritic]];
    }
}

- (NSString *)removeDiacritic { // Taken from: http://stackoverflow.com/a/10932536/1986221
    NSData *data = [NSData dataUsingEncoding:NSASCIIStringEncoding
                       allowsLossyConversion:YES];
    return [[NSString alloc] initWithData:data
                                 encoding:NSASCIIStringEncoding];
}
@end

And then you can simply call:

NSString *helloWorld  = @"hello world";
NSString *capitalized = [helloWorld capitalizeFirst];
NSLog(@"%@ - %@", helloWorld, capitalized);
Alejandro Iván
  • 3,969
  • 1
  • 21
  • 30