How can I determine the location of a deletion in an UITextField - iphone

I'm creating a text field that allows the user to enter a date, and I want to show the format required: mm-dd-yyyy. As they type, it should replace the format with the numbers they type. For instance, if they enter 125, it should look like: 12-5d-yyyy.
I've been able to get this working (using the textField:shouldChangeCharactersInRange:replacementString: method). But there are 2 problems:
When I update the text field so that it shows the format plus what they have typed (by directly setting textField.text) the cursor goes to the end of the inserted text. For example, it currently looks like: 12-30-yyyy| (where | is the cursor), but I want it to look like 12-30-|yyyy. So how can I place the cursor where they last typed?
I have not been able to determine where a deletion occurs if the user presses backspace or delete. The only way I know to determine that they pressed backspace or delete is like this: BOOL thisIsBackspace = ([string length] == 0) (where string is the value of replacementString:. But this doesn't tell me where it occurred. So how can I determine where a deletion occurs in UITextField?

Using the UIDatePicker would be the way to go. Aside from that...
In textField:shouldChangeCharactersInRange: the range parameter will tell you where where in the field the actual change is occurring.
You can also use stringByReplacingCharactersInRange to create the value of the field after edit. Then you can use it to compare and find where they edited.
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *text = [textField.text stringByReplacingCharactersInRange:range withString:string];
// Now you can compare text and textField.text and find where they are different.
return YES;
}

You can place the cursor by using:
[textField setSelectedRange:NSMakeRange(desiredPosition, 0)];
You can determine where the deletion was made by using the "range" input for the method
textField:shouldChangeCharactersInRange:replacementString:

Related

iPhone : Textfields and NSNumberFormatter

I am making an app with multiple textfields. I would like when the user enters a number in the textfield, to automatically add the percent symbol when editing ends. Right now, the only way i know how to do that is to convert the text value to float, then use NSNumberFormatterPercentStyle and then send back the value. I guess that there should be a simpler and faster way to do that for multiple textfileds. Does anyone know?
You could use the UITextFieldDelegate's textFieldDidEndEditing: method.
For example:
- (void)textFieldDidEndEditing:(UITextField *)textField {
NSString *oldTextFieldValue = textField.text;
textField.text = [NSString stringWithFormat:#"%# %%",oldTextFieldValue];
}
Note the double "%" in the stringWithFormat: method: this is because a single % on its own is a "format specifier" and will not be taken into account and xcode will give you a warning, so you need to protect it with a second %.

Keypressed event in UITextField

I have 10 textfields, in which I could enter only one character in each textfield. After a character is entered in each textfield, the focus should move to the next one. Similarly when i delete character from a textfield by pressing the backspace or delete, i need to get the focus to the previous textfield. If I could get the keypressed event, I could do that. Right now I am not able to find any keypressed event examples.
Implement UITextFieldDelegate.
Implement the delegate methods in the protocol. You can achieve the things you wanted.
You can set the focus by using the method becomeFirstResponder to the required textfield.
Have a look at the delegate method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
The text field calls this method whenever the user types a new character in the text field or deletes an existing character.
So that could solve your problem.
Based on Aadhira's answer, but taking into account Kirk Woll's comment, you can generate what the latest text will be by using stringByReplacingCharactersInRange:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *value = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSLog(#"value: %#", value);
return YES;
}
Just to give you directions:
Assign tag to each text field.
Implement UITextFieldDelegate. There are all the methods you need to detect any event that takes place inside the text field. In each method you can check the tag and move focus properly.
Hint: you can use [mainView viewWithTag:XX] to quickly pick the text field you need.
Each time the text is changed you can check the text property of the text field and it will give you the answer which button was pressed.
you have to implement the UITextFieldDelegate protocol into your code and this method will tell you when you start begin editing in text field
– textFieldShouldBeginEditing:
and you can set the if condition in this method according to your requirement...
You have to use the textfieldDelegate methods.
In your textFieldShouldReturn method you have to set your responders like
if (textfield == textField1)
{
[textField2 becomeFirstResponder];
}
else if (textField == textField2)
{
[textField3 becomeFirstResponder];
}
else
{
[textField3 resignFirstResponder];
}
return YES; // as method return type is BOOL.

Replace a given string with an other on UITextView

On my app I need to do this: when a character is typed on TextView to be saved on a NSString and after that to be replace with '*'. I tried this :
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSLog(#"typing...");
text=#"*";
passwordText=textView.text;
NSLog(#"password %#",passwordText);
NSString* nextText = [textView.text stringByReplacingCharactersInRange:range withString:text];
textView.text=nextText;
NSLog(#"next %#",nextText);
NSLog(#"textview.text %#",textView.text);
return YES;
}
where passwordText is the NSString in which I want to save the text introduce from keyboard on UITextView.
The result is this : http://i54.tinypic.com/2cx9ueo.png (here I introduced 'we' and I see this :'*w*e'. Can anyone help me to solve this?
I mention that I must do this using UITextView, and not UITextField.
I can tell you why you get character along with the *, though i am not sure whether your approach is worth to go through this.
make your return statement as NO, this will discard the new key pressed. The YES is currently placing that character next to your programmatic '*'.
Just return a NO in the method if you want the change to be immediate. If you want it to be a little delayed (i.e. first show a character then replace with * like in password fields), return a YES and run another method from the
textView:shouldChangeTextInRange:replacementText: method to be fired after 0.5 seconds (or another number if you like) using a timer.
This new method can replace the last added character or changed character with a *.

How to set numeric keypad while clicking on texbox with decimal format?

I want numeric keypad which automatically convert the value of textbox into decimal format.for example user types 10 it automatically convert .10
Try the following:
NSString * userInput = textBox.text;
textBox.text = [NSString stringWithFormat:#".%#", userInput];
If you need the value as an integer for other use, try:
int userInput = [textBox.text intValue];
textBox.text = [NSString stringWithFormat:#".%d", userInput];
Also, if you need to know the method to do this in real-time, use:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; {
Make sure to return YES so that the character gets added! Hope that Helps!
Go for keyboardType property of text field and have ur wanted keyboard type. Set that to UIKeyboardTypeNumberPad

iPhone Keyboard Filter Question

I want to limit the character users can type in iPhone's keyboard, so I created an array of my own. e.g. The array including 0~9 and a dot to enable users to type a price. Then I can return NO for -(BOOL)textField:shouldChangeCharactersInRange:replacementString: if the replace string is not in the array.
The problem is that the backspace button is also disabled when I use this array to filter text. Any ideas about how to enable backspace button?
Another problem is that I want to let users type their names and therefore I don't want to let them switch to numbers and punctuaction (backspace button is also locked if I use an array to filter). How to disable the switch button on the keyboard (Now I just limit them to type a~z, blank and "." , but I think disable the switch button might be a better way)?
I find a way (maybe not good enough, but it can do the work for backspace function):
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField == txtChargeAmt)
{
if(string.length == 0) //backspace button is pressed
{
textField.text = [textField.text substringToIndex:(textField.text.length - 1)];
return NO;
}
for(NSString *s in arrNumberAndDot)
{
if([string isEqualToString:s])
{
return YES;
}
}
return NO;
}
else
return YES;
}
Other ideas about the backspace issue are welcomed. And how to disable the switch button then?
I guess I am not sure why you would want to use the same TextField for these two different types of input.
I would have two fields, an alphanumeric field for name entry and a numeric field for number entry.
Or am I not getting your question?
This will do what you want a little more succinctly (and efficiently):
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
NSCharacterSet *validCharacterSet = [NSCharacterSet characterSetWithCharactersInString:#".0123456789"];
BOOL shouldChange =
[string length] == 0 || // deletion
textField != txtChargeAmt || // not the field we care about
[string rangeOfCharacterFromSet:validCharacterSet].location != NSNotFound;
if (!shouldChange)
{
// Tell the user they did something wrong. There's no NSBeep()
// on the iPhone :(
}
return shouldChange;
}
I'd construct that character set somewhere else so you you'd only have to do it once, but you get the idea. Anyone have any thoughts on what to do to alert the user they used an invalid character? I'm trying to solve a similar problem.