Replace a given string with an other on UITextView - iphone

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 *.

Related

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

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:

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 %.

Disable a particular key in UI Keyboard

It need to disable '&' key from number and punctuation keyboard, so is it possible to disable a particular key in UIKeyboard?
I don't think it's possible to disable a certain key (unless it's one of the action keys such as the return key) but if you are using a UITextField you can use the - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string delegate method to see if the user pressed the & key and remove it from the string
You cannot do that. However your options are:
create your own custom keyboard not offerring '&' key (too much effort IMO)
If you use UITextField you can validate the text submitted by user: remove '&' and/or inform user that it is not allowed to use '&' (much easier).
EDIT: you can also connect UITextField's "Editing Changed" event to the File's Owner's IBAction and filter out '&' there.
There is one delegate method for textField in which you can block specific characters if you want based on their ASCII values. The method can be written as follows:
-(BOOL)keyboardInput:(id)k shouldInsertText:(id)i isMarkedText:(int)b
{
char s=[i characterAtIndex:0];
if(selTextField.tag==1)
{
if(s>=48 && s<=57 && s == 38) // 48 to 57 are the numbers and 38 is the '&' symbol
{
return YES;
}
else
{
return NO;
}
}
}
This method will permit only numbers and & symbol to be entered by the user. Even if the user presses other characters they won't be entered. And as it is a textField's delegate method you don't need to worry about calling it explicitly.
//Disabling the '<' '>' special characters key in Keyboard in my code
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSCharacterSet *nonNumberSet = [NSCharacterSet characterSetWithCharactersInString:#"<>"];
if (range.length == 1)
return YES;
else
return ([text stringByTrimmingCharactersInSet:nonNumberSet].length > 0);
return YES;
}

iphone setting UITextView delegate breaks auto completion

I have a UITextField that I would like to enable auto completion on by:
[self.textView setAutocorrectionType:UITextAutocorrectionTypeYes];
This works normally, except when I give the UITextView a delegate. When a delegate is set, auto complete just stops working. The delegate has only the following method:
- (void)textViewDidChange:(UITextView *)textView
{
self.textView.text = [self.textView.text stringByReplacingOccurrencesOfString:#"\n" withString:#""];
int left = LENGTH_MAX -[self.textView.text length];
self.characterCountLabel.text = [NSString stringWithFormat:#"%i",abs(left)];
}
Does anyone know how to have both auto complete enabled and a delegate set?
Thanks!Tristan
It's probably breaking autocompletion because you're simultaneously modifying the text in the UITextView.
NSRange r= [self.textView.text rangeOfString:#"\n"];
if(r.location!=NSNotFound) //must check before replacing new lines right away, otherwise spellcheck gets broken
{
self.textView.text = [self.textView.text stringByReplacingOccurrencesOfString:#"\n" withString:#""];
}
The problem was caused by doing something that potentially modifies the text every time it was changed (ie calling replace method). The solution was to only call the replace method when it was necessary.
Get this: All you need to do is remove UITextViewDelegate from your interface (.h) file.
You can still set the delegate to the textView in the nib.
Odd, right? Worked for me, I hope it would solve your problem as well.

How to dissallow certain characters in a UITextview

I have a uitextview that is editable but there are certain characters I would like to be disallowed from being typed.
How can I do that?
You can do this by assigning a delegate to the UITextView, and implementing the following method in the delegate:
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
In the body just write some code that scans through the input text to see if you find the characters you want to filter, if you see them return NO, otherwise return YES.
Unfortunately, this is not that simple, because textView:shouldChangeTextInRange: replacementText: is not necessarilly called with one-character strings. It is for keyboard input, but it isn't when pasting, or when using speech recognition to enter text.
So what do you want to do if the user pastes (or dictates) a string that contains forbidden characters? You might want to let all valid text go through and only delete (or replace) unwanted characters.
The incorrect idea would be to fix the text in the textViewDidChange: delegate routine. While this seems to work, it somehow prevents speech input from working in the UITextView.
The correct idea is to implement textView:shouldChangeTextInRange: replacementText: with full filtering. Here is a sample implementation that filters out newlines:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if([text isEqualToString:#"\n"]) {
[textView resignFirstResponder]; // dismiss keyboard
return NO;
}
text = [text stringByReplacingOccurrencesOfString:#"\n" withString:#" "]; // replace by spaces
NSString *fullText = [textView.text stringByReplacingCharactersInRange:range withString:text];
textView.text = fullText;
return NO;
}
Note that it dismisses the keyboard when the user strikes the enter key. But not quite perfectly: it will also dismiss the keyboard when the user pastes a single newline character. This might be a problem, but this should happen only rarely.