How should I handle text formatting in iOS? I'm not talking about Currency or Decimal styles. Since iOS doesn't have setFormat(), it's kind of complicated.
Two examples of the format I want: 123.456.789-10 and 123.456.789/1000-00.
My aim is to format a text field as the user types. Like any normal site does when, for example, you type a phone number. It doesn't comes from a model or anything. The user just needs to type the numbers and when necessary I'll insert the ".","/" or "-".
You can use regular expressions to do formatting, like this:
NSRegularExpression *fmt = [NSRegularExpression
regularExpressionWithPattern:#"(.{1,3})(.{1,3})(.{1,3})(.{1,2})"
options:0
error:NULL];
NSMutableString *str = [NSMutableString stringWithString:#"12345678910"];
[fmt replaceMatchesInString:str
options:0
range:NSMakeRange(0, str.length)
withTemplate:#"$1.$2.$3-$4"];
This transforms the string into 123.456.789-10
In order to apply this formatting dynamically as users type, create NSRegularExpression *fmt upfront, store it in your UITextFieldDelegate, and use it in your textField:shouldChangeCharactersInRange:replacementString: method.
I created my own method a couple days ago for checking for valid temperature input. It was a bit of a pain as well because I had to check for:
-only numbers
-only one decimal point
-if there was a negative sign it had to be at the front
I ended up using [my string characterAtIndex:index]; and checking each character, since i would have no more than 4 characters.
EDIT:
Here is some pseudo code
for (every char in your string)
if(the index of the char % 3 == 2) //every third char, 0,2,5...
the char must be a . or / or -
else
the char must be a number
Related
I have an NSString and would like to check if a given character at a certain index is an emoji.
However, there doesn't seem to be any reliable way to create an NSCharacterSet of emoji characters, since they change from iOS update to update. And a lot of the available solutions rely on Swift features such as UnicodeScalar. All solutions seem to involve hardcoding the codepoint values for emojis.
As such, is it possible to check for emojis at all?
It's a bit of a complicated question because Unicode is complicated, but you can use NSRegularExpression to do this:
NSString *s = #"where's the emoji 😎 ?";
NSRegularExpression *r = [NSRegularExpression regularExpressionWithPattern:#"\\p{Emoji_Presentation}" options:0 error:NULL];
NSRange range = [r rangeOfFirstMatchInString:s options:0 range:NSMakeRange(0, s.length)];
NSLog(#"location %lu length %lu", (unsigned long)range.location, (unsigned long)range.length);
produces:
2019-01-16 18:07:42.629 emoji[50405:6837084] location 18 length 2
I'm using the \p{Unicode property name} pattern to match characters which have the specified Unicode property. I'm using the property Emoji_Presentation to get those character which present as Emoji by default. You should review Unicode® Technical Standard #51 — Annex A: Emoji Properties and Data Files and the data files linked in A.1 to decide which property you actually care about.
I have been having a lot of trouble with NSString's stringWithFormat: method as of late. I have written an object that allows you to align N lines of text (separated by new lines) either centered, right, or left. At the core of my logic is NSString's stringWithFormat. I use this function to pad my strings with spaces on the left or right of individual lines to produce the alignment I want. Here is an example:
NSString *str = #"$3.00" --> 3 dollars
[NSString stringWithFormat:#"%8s", [str cStringUsingEncoding:NSUnicodeStringEncoding]] --> returns --> " $3.00"
As you can see the above example works great, I padded 3 spaces on the left and the resulting text is right aligned/justified. Problems begin to arise when I start to pass in foreign currency symbols, the formatting just straight up does not work. It either adds extra symbols or just returns garbage.
NSString *str = #"Kč1.00" --> 3 Czech Koruna (Czech republic's currency)
[NSString stringWithFormat:#"%8s", [str cStringUsingEncoding:NSUnicodeStringEncoding]] --> returns --> " Kč1.00"
The above is just flat out wrong... Now I am not a string encoding expert but I do know NSString uses the international standardized unicode encoding for special characters well outside basic ASCII domain.
How can I fix my problem? What encoding should I use? I have tried so many different encoding enums I have lost count, everything from NSMACOSRomanEncoding to NSUTF32UnicodeBigEndian.. My last resort will be to just completely ditch using stringWithFormat all together, maybe it was only meant for simple UTF8Strings and basic symbols.
If you want to represent currency, is a lot better if you use a NSNumberFormatter with currency style (NSNumberFormatterCurrencyStyle). It reads the currentLocale and shows the currency based on it. You just need to ask its string representation and append to a string.
It will be a lot easier than managing unicode formats, check a tutorial here
This will give you the required result
NSString *str = #"Kč1.00";
str=[NSString stringWithFormat:#"%#%8#",[#" " stringByPaddingToLength:3 withString:#" " startingAtIndex:0],str];
Out Put : #" Kč1.00";
Just one more trick to achieve this -
If you like use it :)
[NSString stringWithFormat:#"%8s%#",[#"" cStringUsingEncoding:NSUTF8StringEncoding],str];
This will work too.
How can I parse out the area code from any given phone number? For example, if I enter in 208-399-2777, the 208 is the area code in the United States. However, in Brazil, the phone number 78 5239-6822 has a 2-digit area code.
Does NSTextCheckingResult provide any of this functionality?
Depending on the complexity of your problem where tinkering with the string may not work and you may want to know more about the area code, check out Google's libphonenumber https://code.google.com/p/libphonenumber/, there is a wrapper for Objective C https://github.com/iziz/libPhoneNumber-iOS.
This will get the first "set" of numbers in the phone number string
NSString *pattern = #"^\\d+";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:pattern
options:0
error:nil];
Explanation:
^ matches the beginning of a string
\d+ matches one or more numbers
Note: If your phone numbers are formatted without spaces (e.g., 1234567890) it will not work.
So as I work my way through understanding string methods, I came across this useful class
NSCharacterSet
which is defined in this post quite well as being similar to a string excpet it is used for holding the char in an unordered set
What is differnce between NSString and NSCharacterset?
So then I came across the useful method invertedSet, and it bacame a little less clear what was happening exactly. Also I a read page a fter page on it, they all sort of glossed over the basics of what was happening and jumped into advanced explainations. So if you wanted to know what this is and why we use It SIMPLY put, it was not so easy instead you get statements like this from the apple documentation: "A character set containing only characters that don’t exist in the receiver." - and how do I use this exactly???
So here is what i understand to be the use. PLEASE provide in simple terms if I have explained this incorrectly.
Example Use:
Create a list of Characters in a NSCharacterSetyou want to limit a string to contain.
NSString *validNumberChars = #"0123456789"; //Only these are valid.
//Now assign to a NSCharacter object to use for searching and comparing later
validCharSet = [NSCharacterSet characterSetWithCharactersInString:validNumberChars ];
//Now create an inverteds set OF the validCharSet.
NSCharacterSet *invertedValidCharSet = [validCharSet invertedSet];
//Now scrub your input string of bad character, those characters not in the validCharSet
NSString *scrubbedString = [inputString stringByTrimmingCharactersInSet:invertedValidCharSet];
//By passing in the inverted invertedValidCharSet as the characters to trim out, then you are left with only characters that are in the original set. captured here in scrubbedString.
So is this how to use this feature properly, or did I miss anything?
Thanks
Steve
A character set is a just that - a set of characters. When you invert a character set you get a new set that has every character except those from the original set.
In your example you start with a character set containing the 10 standard digits. When you invert the set you get a set that has every character except the 10 digits.
validCharSet = [NSCharacterSet characterSetWithCharactersInString:validNumberChars];
This creates a character set containing the 10 characters 0, 1, ..., 9.
invertedValidCharSet = [validCharSet invertedSet];
This creates the inverted character set, i.e. the set of all Unicode characters without
the 10 characters from above.
scrubbedString = [inputString stringByTrimmingCharactersInSet:invertedValidCharSet];
This removes from the start and end of inputString all characters that are in
the invertedValidCharSet. For example, if
inputString = #"abc123d€f567ghj😄"
then
scrubbedString = #"123d€f567"
Is does not, as you perhaps expect, remove all characters from the given set.
One way to achieve that is (copied from NSString - replacing characters from NSCharacterSet):
scrubbedString = [[inputString componentsSeparatedByCharactersInSet:invertedValidCharSet] componentsJoinedByString:#""]
This is probably not the most effective method, but as your question was about understanding
NSCharacterSet I hope that it helps.
I have a long string. I'd like to take this long string, search for any occurrences of words that appear between quotes (i.e., "string"), and insert a string before the word (i.e., "x"), and a string after the word (i.e., "y").
Any solutions would be most appreciated! Thanks!
I see that I could use the following to grab the text between the quotes:
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"([\"])
(?:\\\\\\1|.)*?\\1" options:0 error:&error];
NSRange range = [regex rangeOfFirstMatchInString:myString options:0 range:NSRangeMake(0,
[myString length]];
However, now I need to replace the text that is inside the quotations, inserting the html tags "bold" before and "/bold" after. Is there anyway for me to do this? Also, if there are multiple occurrences of quoted text in a given string, how would I use the above code to cycle through the string to get modify each piece of quoted text one-by-one?
I came across this post ([click here]]1 but I'm not quite sure how to modify the sample code to achieve the result I want. Any help would be great!
I will refer you to this page: Shortcuts in Objective-C to concatenate NSStrings
The page talks about adding strings together by using two NSMutable strings and adding one to both, which seems to be the preferable of the two it gives. Unfortunately, there is no operation to add two or more strings together (which really sucks).
Try this:
NSString *original=#"The quick 'brown fox' The quick 'brown fox' ";
NSString *target=[original stringByReplacingOccurrencesOfString:#"'brown fox'" withString:#"<b>brown fox</b>"];