Restricting text input to only alpha characters - ios

I have seen multiple approaches to this but cannot get this to work.
I am trying to restrict a text field to only allow alpha characters entered into it. I.e. ABCDEFabcdef (but all of them).
Here is my existing method:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Check for the back space/delete
if (string.length <=0 ) {
if ([self.wordArray lastObject]) {
[self.wordArray removeObjectsInRange:range];
[self.tileCollectionView reloadData];
return YES;
}
}
// Check to make sure the word is not above 16 characters, that should be enough right?
if (textField.text.length >= 16 ) {
NSLog(#"WOOO SLOW DOWN THE TEXT IS ABOVE 16");
return NO;
} else {
[self.wordArray addObject:string];
[self.tileCollectionView reloadData];
return YES;
}
}
At present I check for a back space and remove the last entry from an Array. Also if the letter is accepted then I add the letter as an object to an array, that is for something else. But the logic for the ALPHA check should also take this into account, only if the letter is 'legal' should it add to the array and reload the collection view.

Well, one way you could do it would be to create your own character set to compare against. Then you can take advantage of NSString's stringByTrimmingCharactersInSet: and NSCharacterSet's invertedSet property to remove all characters from the set that don't match the characters you initially specify. Then, if the final string matches the input string, it didn't contain illegal characters.
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
NSString *input = #"a";
NSString *output = [input stringByTrimmingCharactersInSet:[myCharSet invertedSet]];
BOOL isValid = [input isEqualToString:output];
NSLog(#"%d",isValid);

Related

add prefix to UITextField

I want to add prefix of UITextfield text. The UITextfield text length less than 7. How many characters are less than 7, that all replace with zeros.
If text is "1234", add prefix like "0001234".
If text is "12345", add prefix like "0012345".
If text is "123", add prefix like "0000123".
can any one suggest me, how to implement.
It sounds like what we actually want is a numbers-only string that is always 7-characters long, with the left-most characters filled in with padded zeros for anything the user has not entered, correct?
So, we need a handful of methods to make this as easy as possible.
First, this one doesn't make sense right now, but we want a method to remove the zeros we padded at the front (it'll make sense later).
So, borrowing from this Stack Overflow answer...
- (NSString *)stringByRemovingPaddedZeros:(NSString *)string {
NSRange range = [string rangeOfString:#"^0*" options:NSRegularExpressionSearch];
return [string stringByReplacingCharactersInRange:range withString:#""];
}
And we'll borrow from Ilesh's answer for adding the padded zeros:
- (NSString *)stringByAddingPaddedZeros:(NSString *)string padLength:(NSInteger)length {
NSString *padding = [#"" stringByPaddingToLength:(length - string.length) withString:#"0" startingAtIndex:0];
return [NSString stringWithFormat:#"%#%#", padding, string];
}
So now we can go back and forth between padded and unpadded strings, right?
So now, one last step, implementing shouldChangeCharactersInRange:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
newString = [self stringByRemovingPaddedZeros:newString];
newString = [self stringByAddedPaddedZeros:newString padLength:7];
textField.text = [newString subStringToIndex:7];
return NO;
}
We always return NO here, as we're setting the textField.text property manually. Now when there are 7 characters (and no leading zeros), the user can type no more. If there are 7 characters and the user hits backspace, they should all shift right one and a zero added to the front. If there are leading zeros at the front, typing characters should shift everything left and drop a leading zero, and add a new character to the front.
As an additional note, this code does not take care of verifying that the user is only entering digits. Some extra logic would be required for that. I'd simply recommend checking that the replacementString (string) is only digits before you get into any of the other code in shouldChangeCharactersInRange here.
Here printing textfield text on button click. Check the code inside the method.
- (IBAction)logTextFieldText:(id)sender
{
NSMutableString *str=[[NSMutableString alloc]init];
if (_txtf.text.length<7)
{
for (int i=0;i<7-_txtf.text.length; i++)
{
[str appendString:#"0"];
}
[str appendString:_txtf.text];
}
NSLog(#"final text is: %#",str);
}
Implement the UITextFieldDelegate method textFieldDidEndEditing: to pad the 0's in.
- (void)textFieldDidEndEditing:(nonnull UITextField *)textField
{
if (textField.text.length < 7) {
// Create a string of 0's to pad with
NSString *padding = [#"" stringByPaddingToLength:(7 - textField.text.length) withString:#"0" startingAtIndex:0];
NSMutableString *change = [textField.text mutableCopy];
// Insert the 0's string
[change insertString:padding atIndex:0];
textField.text = change;
}
}
If you want to fix the length of UITextField text than use this UITextField delegate method.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (self.txtGet.text.length>=7) {
return NO;
}
return YES;
}
and the completion editing (or done button ) you add this line in before using the UITextField value.
NSString *padding = [#"" stringByPaddingToLength:(7 - self.txtGet.text.length) withString:#"0" startingAtIndex:0];
NSMutableString *change = [self.txtGet.text mutableCopy];
// Insert the 0's string
[change insertString:padding atIndex:0];
self.txtGet.text = change;
I think its helpful to you. Thank you.

Restrict user to enter abuse words in text view

I am developing a application where user has to enter only holy words. I want user to be restricted not to enter the abuse or adult word.
I have a big list of adult or abuse words whenever user will enter that word it should delete it automatically.
Any help will be appreciated.
You are probably using UITextField so you should look after forbidden words after text has changed:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSRange spaceRange = [newString rangeOfString:#" "];
if (spaceRange.location != NSNotFound) { // it's a new word
newString = [self stringWithoutForbiddenWords:newString];
}
textField.text = newString;
return NO; // we set the textField text manually
}
- (NSString *)stringWithoutForbiddenWords:(NSString *)string {
for (NSString *forbiddenWord in self.forbiddenWords) {
NSRange forbiddenWordRange = [string rangeOfString:forbiddenWord];
if (forbiddenWordRange.location != NSNotFound) {
// remove the forbidden word
string = [string stringByReplacingOccurrencesOfString:forbiddenWord withString:#""];
}
}
return string;
}
Don't forget to set you UITextField delegate.
Its a very simple logic , by the way only "Holy Word" seems very funny I hope you meant non-abusive words.
So to restrict abusive words, first make an Array and store all the abusive words in that.
then in textView shouldChangeTextInRange: check whenever user press " space.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if([string isEqualToString:#" "])
{
//now iterate the whole string and find whether any word contains any value from your Abusive words Array and replace the word with blank space or *
}

Adding a constant country code at beginning of UITextField

I have a UITextField that the user require to enter a phone number into it.
This is how it looks like right now:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Auto-add hyphen before appending 4rd or 7th digit
//
//
if (range.length == 0 && (range.location == 3 || range.location == 7))
{
textField.text = [NSString stringWithFormat:#"%#-%#", textField.text, string];
return NO;
}
// Delete hyphen when deleting its trailing digit
//
//
if (range.length == 1 && (range.location == 4 || range.location == 8))
{
range.location--;
range.length = 2;
textField.text = [textField.text stringByReplacingCharactersInRange:range withString:#""];
return NO;
}
// Prevent crashing undo bug – see note below.
//
//
if (range.length + range.location > textField.text.length)
{
return NO;
}
// Limit text field characters
//
//
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 12) ? NO : YES;
}
After the 3rd digit, I'm adding a hyphen and than again. What I'm trying to achieve here is to add a country code as constant at start of the UITextField and that the user will not be able to remove it. Lets say USA country code, then the UITextField text will look like that at start +1- and then after writing the full number it will look like that: +1-600-242-252
How can I do that?
Thanks in advance!
This answer assumes a starting country code string which includes the hyphen at the end, ex: self.countryCode = #"+1-";. The text field should initially contain "+1-".
I've made my answer way more comprehensive than your original intent because it handles many use cases you've overlooked, for example copy and paste operations with multiple characters, inappropriate hyphen deletion, inappropriate hyphen addition, mid-line insertion, etc. It's still not perfect though because your original answer was unspecific in some ways... For example, if you specify that the user should only be able to enter digits, the code can be much cleaner.
The below implementation is described line by line in the comments included throughout.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Combine the new text with the old
NSMutableString *combinedText = [[textField.text stringByReplacingCharactersInRange:range withString:[NSString stringWithFormat:#"%#", string]] mutableCopy];
// If the user deletes part of the country code or tries
// to edit it in any way, don't allow it
if (combinedText.length < self.countryCode.length ||
![combinedText hasPrefix:self.countryCode]) {
return NO;
}
// Limit text field characters to 12
if (combinedText.length > self.countryCode.length + 12) {
return NO;
}
// If the user tries to add a hyphen where there's supposed
// to be a hyphen, allow them to do so.
if ([string isEqualToString:#"-"] &&
(range.location == self.countryCode.length + 3 ||
range.location == self.countryCode.length + 7)) {
return YES;
}
// Remove all the hyphens other than the one directly
// following the country code
[combinedText replaceOccurrencesOfString:#"-" withString:#"" options:0 range:NSMakeRange(self.countryCode.length, [combinedText length] - self.countryCode.length)];
// Auto-add the hyphens before the 4th and 7th digits
if (combinedText.length > self.countryCode.length + 3)
[combinedText insertString:#"-" atIndex:self.countryCode.length + 3];
if (combinedText.length > self.countryCode.length + 7)
[combinedText insertString:#"-" atIndex:self.countryCode.length + 7];
// Store the original cursor position
UITextPosition *pos = [textField selectedTextRange].start;
// Count up the original number of hyphens
NSUInteger originalNumberOfHyphens = [[textField.text componentsSeparatedByString:#"-"] count] - 1;
// Count up the new number of hyphens
NSUInteger newNumberOfHyphens = [[combinedText componentsSeparatedByString:#"-"] count] - 1;
// Create a cursor offset to reflect the difference
// in the number of hyphens
float offset = newNumberOfHyphens - originalNumberOfHyphens;
// Update the text field to contain the combined text
textField.text = combinedText;
// Update the cursor position appropriately
if (string.length > 0) {
UITextPosition* cursor = [textField positionFromPosition:[textField beginningOfDocument] offset:range.location + range.length + offset + string.length];
textField.selectedTextRange = [textField textRangeFromPosition:cursor toPosition:cursor];
} else {
UITextPosition* cursor = [textField positionFromPosition:pos inDirection:UITextLayoutDirectionLeft offset:1-offset];
textField.selectedTextRange = [textField textRangeFromPosition:cursor toPosition:cursor];
}
// No need to replace the string since it's already been done
return NO;
}
To keep a constant at the beginning, you basically want to check if the constant still exist in the proposed text. If it doesn't reject such edits.
You should not try to insert hyphens at specific editing steps. It's better to manipulate the whole string.
E.g.
test if string could be valid. i.e. starts with +1
remove all hyphens you previously added
reinsert all hyphens
In code this would look like this:
- (void)viewDidLoad {
[super viewDidLoad];
self.textField.text = #"+1"; // start with a +1 in the textField otherwise we can't change the field at all
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *proposedText = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (![proposedText hasPrefix:#"+1"]) {
// tried to remove the first +1
return NO;
}
NSString *formattedPhoneNumber = [proposedText substringFromIndex:2]; // without +1 prefix
NSString *unformattedPhoneNumber = [formattedPhoneNumber stringByReplacingOccurrencesOfString:#"-" withString:#""]; // without hypens
// start with the prefix
NSMutableString *newText = [NSMutableString stringWithString:#"+1"];
for (NSInteger i = 0; i < [unformattedPhoneNumber length]; i++) {
if (i % 3 == 0) {
// add a - every 3 characters. add one at the beginning as well
[newText appendString:#"-"];
}
// add each digit from the unformatted phonenumber
[newText appendString:[unformattedPhoneNumber substringWithRange:NSMakeRange(i, 1)]];
}
textField.text = newText;
return NO;
}
This is still a very naive implementation. It has a couple of problems, for example the cursor will always be at the end because we set text of the textField manually. So the user can't easily remove numbers in the middle of the string. Of course there are ways around this. selectedTextRange would be the property to use. And you can't really paste phone numbers into the field. And of course the user can't delete a hyphen.
Formatting while the user is typing tends to get complicated quickly because there are so many edge cases. But that should get you started.

how to check if an alphanumeric character is entered in text filed in iOS

I am having a condition in which i want to check if there are any special characters entered in textfield.
If there are no special characters entered it should return YES. If a special character is entered in textfield a check is made to check if the special character is from a set characters. If the special entered is not from the set of special characters it should return NO.
This is my code:
NSCharacterSet *newrang = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"] invertedSet];
NSRange newrange = [pwd rangeOfCharacterFromSet:newrang];
if (!newrange.length)
{
return YES;
}
else
{
NSCharacterSet* set =
[[NSCharacterSet characterSetWithCharactersInString:#"!##$%^&*"] invertedSet];
NSRange checkrange = [pwd rangeOfCharacterFromSet:set];
if (checkrange.location==NSNotFound)
{
NSLog(#"NO");
}
else
{
NSLog(#"YEs");
}
if ([pwd rangeOfCharacterFromSet:set].location == NSNotFound) {
return NO;
} else {
return YES;
}
}
My problem is if i enter abc#_123 it is returning YES. Instead it should return NO coz an invalid special character:
"_"
is present .
Thanks
Create NSCharacterSet of characters that you want to block like i created alphanumericCharacterSet invertedSet. Then validate every character with UITextFieldDelegate method textField:shouldChangeCharactersInRange:replacementString: as The text field calls this method whenever the user types a new character in the text field or deletes an existing character.
Review this hope this will help you
NSCharacterSet *blockCharacters = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789##"] invertedSet];
- (BOOL)textField:(UITextField *)field shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)characters
{
return ([characters rangeOfCharacterFromSet:blockCharacters].location == NSNotFound);
}

Objective-c How to do validation on textField

I would like to prevent the user from not entering any data as well as entering only spaces. So basically there must at least be one character without a space. Then I would also like to remove any spaces at the beginning of the word so the first letter is a character that is not a space.
edit
the user must enter something and if the user enters a few spaces before it then I want to trim those spaces. I also want to prevent the user from just entering spaces.
Example
if the user enter's a name and surname like " James Dean" I would like to take the first space away but not the second space between James and Dean.
Set your UIViewController to be your destination UITextField's delegate and implement this method:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// verify the text field you wanna validate
if (textField == _nameTextField) {
// do not allow the first character to be space | do not allow more than one space
if ([string isEqualToString:#" "]) {
if (!textField.text.length)
return NO;
if ([[textField.text stringByReplacingCharactersInRange:range withString:string] rangeOfString:#" "].length)
return NO;
}
// allow backspace
if ([textField.text stringByReplacingCharactersInRange:range withString:string].length < textField.text.length) {
return YES;
}
// in case you need to limit the max number of characters
if ([textField.text stringByReplacingCharactersInRange:range withString:string].length > 30) {
return NO;
}
// limit the input to only the stuff in this character set, so no emoji or cirylic or any other insane characters
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 "];
if ([string rangeOfCharacterFromSet:set].location == NSNotFound) {
return NO;
}
}
return YES;
}
try like this may be it helps to you,here is my code
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string{
if([text.text length]==0){
if([string isEqualToString:#" "]){
return NO;
}
}
return YES;
}
By placing this code user won't enter space as a first letter but it accepts the space in the middle of the string.
I'll give you a hint for the first part.
NSString *tempname1 = [self.textField.text stringByReplacingOccurrencesOfString:#" " withString:#""];
BOOL thereAreJustSpaces = [tempname1 isEqualToString:#""];
-(void)removeSpacesFromTextFields:(id) sender {
NSString *trim = [self.FNTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([trim length] == 0) {
self.FNTextField.text = #"";
}
}
Try this, If you want to prevent space in your text field.
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(checkSpace:) name:UITextFieldTextDidChangeNotification object:textfield];
}
-(void)checkSpace:(NSNotification *)notification
{
str = [textfield.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] ;
textfield.text=str;
}

Resources