iphone string initial char before space - iphone

I have a question...
I wish take from a string that contains a name and surname, the initial of the first and the surname complete....
example:
NSString* myName = #"Mel Gibson";
//I Wish have "M Gibson";
NSString* myName2 = #"Leonardo Di Caprio";
//I wish have "L Di Caprio";
Thanks

#implementation NSString (AbbreviateFirstWord)
-(NSString*)stringByAbbreviatingFirstWord {
// step 1: Locate the white space.
NSRange whiteSpaceLoc = [self rangeOfString:#" "];
if (whiteSpaceLoc.location == NSNotFound)
return self;
// step 2: Remove all characters between the first letter and the white space.
NSRange rangeToRemove = NSMakeRange(1, whiteSpaceLoc.location - 1);
return [self stringByReplacingCharactersInRange:rangeToRemove withString:#""];
}
#end

Related

Trimmed values while parsing XML file [duplicate]

I'm new with iOS developing and i'm looking for a solution to compare two String ignoring the spaces at the beginning or at the ending. For example, "Hello" == "Hello " should return true.
I've serached for a solution but i didn't find nothing in Swift. Thanks
I would recommend you start by trimming whitespace from the String with this Swift code:
stringToTrim.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
NSString *string1 = #" Hello";
//remove(trim) whitespaces
string1 = [string1 stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *string2 = #"Hello ";
//remove(trim) whitespaces
string2 = [string1 stringByReplacingOccurrencesOfString:#" " withString:#""]
// compare strings without whitespaces
if ([string1 isEuqalToString:string2]) {
}
So if you want to use it directly -
if ([[yourString1 stringByReplacingOccurrencesOfString:#" " withString:#""] isEuqalToString:[yourString2 stringByReplacingOccurrencesOfString:#" " withString:#""]]) {
// Strings are compared without whitespaces.
}
Above will remove all whitespaces of your string, if you want to remove only leading and trailing whitespaces then there are a couple of post already available, you can create a category of string as mentioned in following stack overflow post - How to remove whitespace from right end of NSString?
#implementation NSString (TrimmingAdditions)
- (NSString *)stringByTrimmingLeadingCharactersInSet:(NSCharacterSet *)characterSet {
NSUInteger location = 0;
NSUInteger length = [self length];
unichar charBuffer[length];
[self getCharacters:charBuffer];
for (location; location < length; location++) {
if (![characterSet characterIsMember:charBuffer[location]]) {
break;
}
}
return [self substringWithRange:NSMakeRange(location, length - location)];
}
- (NSString *)stringByTrimmingTrailingCharactersInSet:(NSCharacterSet *)characterSet {
NSUInteger location = 0;
NSUInteger length = [self length];
unichar charBuffer[length];
[self getCharacters:charBuffer];
for (length; length > 0; length--) {
if (![characterSet characterIsMember:charBuffer[length - 1]]) {
break;
}
}
return [self substringWithRange:NSMakeRange(location, length - location)];
}
#end
Now once you have the methods available, you can call these on your strings to trim leading and trailing spaces like -
// trim leading chars
yourString1 = [yourString1 stringByTrimmingLeadingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// trim trainling chars
yourString1 = [yourString1 stringByTrimmingTrailingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// trim leading chars
yourString2 = [yourString2 stringByTrimmingLeadingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// trim trainling chars
yourString2 = [yourString2 stringByTrimmingTrailingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// compare strings
if([yourString1 isEqualToString: yourString2]) {
}
For Swift 3.0+
Use .trimmingCharacters(in: .whitespaces) before comparison or .trimmingCharacters(in: .whitespacesAndNewlines)
In Swift 4
Use it on any String type variable.
extension String {
func trimWhiteSpaces() -> String {
let whiteSpaceSet = NSCharacterSet.whitespaces
return self.trimmingCharacters(in: whiteSpaceSet)
}
}
And Call it like this
yourString.trimWhiteSpaces()

Objective-C: Find consonants in string

I have a string that contains words with consonants and vowels. How can I extract only consonants from the string?
NSString *str = #"consonants.";
Result must be:
cnsnnts
You could make a character set with all the vowels (#"aeiouy")
+ (id)characterSetWithCharactersInString:(NSString *)aString
then use the
- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set
method.
EDIT: This will only remove vowels at the beginning and end of the string as pointed out in the other post, what you could do instead is use
- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator
then stick the components back together. You may also need to include capitalized versions of the vowels in the set, and if you want to also deal with accents (à á è è ê ì etc...) you'll probably have to include that also.
Unfortunately stringByTrimmingCharactersInSet wont work as it only trim leading and ending characters, but you could try using a regular expression and substitution like this:
[[NSRegularExpression
regularExpressionWithPattern:#"[^bcdefghjklmnpqrstvwx]"
options:NSRegularExpressionCaseInsensitive
error:NULL]
stringByReplacingMatchesInString:str
options:0
range:NSMakeRange(0, [str length])
withTemplate:#""]
You probably want to tune the regex and options for your needs.
Possible, for sure not-optimal, solution. I'm printing intermediate results for your learning. Take care of memory allocation (I didn't care). Hopefully someone will send you a better solution, but you can copy and paste this for the moment.
NSString *test = #"Try to get all consonants";
NSMutableString *found = [[NSMutableString alloc] init];
NSInteger loc = 0;
NSCharacterSet *consonants = [NSCharacterSet characterSetWithCharactersInString:#"bcdfghjklmnpqrstvwxyz"];
while(loc!=NSNotFound && loc<[test length]) {
NSRange r = [[test lowercaseString] rangeOfCharacterFromSet:consonants options:0 range:NSMakeRange(loc, [test length]-loc)];
if(r.location!=NSNotFound) {
NSString *temp = [test substringWithRange:r];
NSLog(#"Range: %# Temp: %#",NSStringFromRange(r), temp);
[found appendString:temp];
loc=r.location+r.length;
} else {
loc=NSNotFound;
}
}
NSLog(#"Found: %#",found);
Here is a NSString category that does the job:
- (NSString *)consonants
{
NSString *result = [NSString stringWithString:self];
NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:#"aeiou"];
while(1)
{
NSRange range = [result rangeOfCharacterFromSet:characterSet options:NSCaseInsensitiveSearch];
if(range.location == NSNotFound)
break;
result = [result stringByReplacingCharactersInRange:range withString:#""];
}
return result;
}

Uppercase first letter in NSString

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.
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. ;)
nil will observe any method call you send to it.
So it will digest anything you try on it, nil is your friend.
You can use NSString's:
- (NSString *)capitalizedString
or (iOS 6.0 and above):
- (NSString *)capitalizedStringWithLocale:(NSLocale *)locale
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]];
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 :)
Since iOS 9.0 there is a method to capitalize string using current locale:
#property(readonly, copy) NSString *localizedCapitalizedString;
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]];
}
}
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);

Truncate a string and add ellipsis at the end in Objective-c

How to truncate a string in Objective-C and then add the ellipsis at the end?
NSString *origString = #"A very long string blah blah blah";
const int clipLength = 18;
if([origString length]>clipLength)
{
origString = [NSString stringWithFormat:#"%#...",[origString substringToIndex:clipLength]];
}
Use one of these NSString methods to truncate, probably the last:
– substringFromIndex:
– substringWithRange:
– substringToIndex:
and then use the NSString method
– stringByAppendingString:
to add #"..." or whatever ellopsis you like.
For example:
NSString *newString = [[string substringToIndex:12] stringByAppendingString:#"..."];
For your reading pleasure, I recommend the NSString Class Reference.
In case you wish to truncate and add ellipsis to a string with the maximum being a specific width, here is an implementation that takes into account font and size:
+ (NSString *)stringByTruncatingString: (NSString *)string toWidth: (CGFloat)width withFont: (UIFont *)font
{
#define ellipsis #"..."
NSMutableString *truncatedString = [string mutableCopy];
if ([string sizeWithAttributes: #{NSFontAttributeName: font}].width > width) {
width -= [ellipsis sizeWithAttributes: #{NSFontAttributeName: font}].width;
NSRange range = {truncatedString.length - 1, 1};
while ([truncatedString sizeWithAttributes: #{NSFontAttributeName: font}].width > width) {
[truncatedString deleteCharactersInRange:range];
range.location--;
}
[truncatedString replaceCharactersInRange:range withString:ellipsis];
}
return truncatedString;
}
Don't need chuck of code for do this..
the easiest way to do this,
for drawRect
- (void)drawRect:(NSRect)dirtyRect{
NSString *theText = #"bla blah bla bhla bla bla";
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByTruncatingTail];
[theText drawInRect:dirtyRect withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:style, NSParagraphStyleAttributeName,nil]];
}
hear I use dirtyRect for String's Drawing area you can change it as you wish.
for NSTextField
NSTextField *_warningTF = [[NSTextField alloc]init];
[_warningTF setStringValue:#"sfdsf sdfdsfdsfdsfdsfdsfdsf 1234566789123456789sfdsf dsf dsfdsf"];
[_warningTF.cell setLineBreakMode:NSLineBreakByTruncatingTail];
I wrote simple category to truncate NSString by words:
#interface NSString (TFDString)
- (NSString *)truncateByWordWithLimit:(NSInteger)limit;
#end
#implementation NSString (TFDString)
- (NSString *)truncateByWordWithLimit:(NSInteger)limit {
NSRange r = NSMakeRange(0, self.length);
while (r.length > limit) {
NSRange r0 = [self rangeOfString:#" " options:NSBackwardsSearch range:r];
if (!r0.length) break;
r = NSMakeRange(0, r0.location);
}
if (r.length == self.length) return self;
return [[self substringWithRange:r] stringByAppendingString:#"..."];
}
#end
Usage:
NSString *xx = #"This string is too long, somebody just need to take and truncate it, but by word, please.";
xx = [xx truncateByWordWithLimit:50];
Result:
This string is too long, somebody just need to...
Hope it helps somebody.
the drawWithRect:options:attributes:context method helps. you can try this:
[_text drawWithRect:_textRect options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine attributes:attributes context:nil];

How to know the length of NSString that fits a UILabel with fixed size?

I know NSString has methods that determine the frame size for it, using NSString UIKit Additions, sizeWithFont......
How about the other way around? I mean if I have a fixed frame size, how do I know how many characters or words for a NSString that can fit into it?
If I know this, I can cut off the NSString easily.
thanks
It might not be the most elegant solution, but you could do something like this:
- (NSString *)string:(NSString *)sourceString reducedToWidth:(CGFloat)width withFont:(UIFont *)font {
if ([sourceString sizeWithFont:font].width <= width)
return sourceString;
NSMutableString *string = [NSMutableString string];
for (NSInteger i = 0; i < [sourceString length]; i++) {
[string appendString:[sourceString substringWithRange:NSMakeRange(i, 1)]];
if ([string sizeWithFont:font].width > width) {
if ([string length] == 1)
return nil;
[string deleteCharactersInRange:NSMakeRange(i, 1)];
break;
}
}
return string;
}
Then call it like this:
NSString *test = #"Hello, World!";
CGFloat width = 40.0;
UIFont *font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
NSString *reducedString = [self string:test reducedToWidth:width withFont:font];
NSLog(#"%#", reducedString);
You cannot know/determine the number of characters that fits in a UILabel with fixed width because some characters are smaler than others, eg l and m.
There are two options:
Use Mono-Space-Fonts (each character has also a fixed width). Then determine the width for one char in your font with your font-size and calculate the number of chars
Allow any number of characters and check on insert if the inserted characters fit.
You have to know what behaviour you want to have. What should happen if there is text that does not fit. If you only want to truncate (like the solution of mortenfast does) then just use UILineBreakModeTailTruncation for the lineBreakMode-property of your UILabel (there are more options, like TruncateHead, Clip, Word Wrap)
Or you just just use the lineBreak property and set it to NSLineBreakByCharWrapping and move on with your life. https://stackoverflow.com/a/29088337/951349
Thanks #Morten. I've updated the sample code to handle word separation. It also eliminates extra spaces in between words. It has not been tested in the field, but my tests have, thus far, proven OK. Please update at your leisure if you find improvements or bug/glitch fixes.
-(NSString*)string:(NSString*)sourceString reducedToWidth:(CGFloat)width withFont:(UIFont*)font {
// if full string is within bounds, simply return the full string
if( [sourceString sizeWithFont:font].width <= width ) return sourceString;
// break up string into words. if <= 1 word, return original string
NSArray* words = [sourceString componentsSeparatedByString:#" "];
NSInteger numWords = [words count];
if( numWords <= 1 ) return sourceString;
// our return var. we populate as we go
NSMutableString* str = [NSMutableString string];
// temp var to test with before adding to return string
NSMutableString* strTemp = [NSMutableString string];
// string to hold word LESS spaces
NSString* strWordTemp = nil;
// the word we're currently on
NSInteger numWord = 0;
// whether we need to add a space (when not last word)
Boolean addSpace = NO;
// loop through our words....
for( NSString* strWord in words ) {
// which word we're on
numWord++;
// eliminate white space
strWordTemp = [strWord stringByReplacingOccurrencesOfString:#" " withString:#""];
// if this word is empty or was a space(s), skip it
if( [strWordTemp isEqualToString:#""] ) continue;
// append to temp string
[strTemp appendString:strWordTemp];
// if we're still within the bounds...
if( [strTemp sizeWithFont:font].width <= width ) {
// default = no extra space
addSpace = NO;
// if we're not the last word, add a space & check for length
if( numWord < numWords ) {
[strTemp appendString:#" "];
// if adding space made it too long, then just don't add it!
if( [strTemp sizeWithFont:font].width > width ) {
// it was too long with space, so we'll just add word
[str appendString:strWordTemp];
break;
}
// otherwise, it's OK to add the space
else addSpace = YES;
}
// append to return string and continue
[str appendFormat:#"%#%#", strWordTemp, ( addSpace ? #" " : #"" )];
}
// otherwise, we're done
else break;
}
// return our result
return str;
}