I created a UITextView which allows dynamic tagging when the user types #.
Is it possible to detect a # removed, in order to stop my specific tagging process that I created? If so, how can I do that? UITextView has no such delegate methods.
I would use
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
Then create an NSString in which you store the last character added to the UITextView. Within the above method, add the following snippet.
if ([text isEqualToString:#""] && [lastRecordedString isEqualToString#"#"]) {
//do whatever you want to do when an # is deleted
}
lastRecordedString = [textView.text substringFromIndex:[string length]-1];
EDIT: see the edited code above. Now lastRecordedString is the last character in the UITextView after a character is removed. This should work.
You can get the original text which will be replaced by use:
NSString *originalText = [textView.text substringWithRange:range];
in your
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
method.
Then, do
if ([originalText rangeOfString:#"tag"].length > 0) {
NSLog(#"delete tag string");
}
You will detect if user delete a specific string.
Hope that helpful!
Related
I'm using UITextView in my application, i want user to enter maximum 5 lines of text, I've been spending a few days on google but still have no luck, can some one please help!!
PS: Not limit number of characters but number of "LINES"
I've tried finding number of lines and use this method textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text , return NO when limit is reached but the back space button doesn't work after limit reached.
Thanks!
If the lines are not automatically wrapped you could use this:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]) {
rows++;
if(rows >= maxNumberOfLines){
//Exit textview
return NO;
}
}
return YES;
}
This should work, but it's not the best way to deal with it.
It would probably be better to use the size of the string and compare it to the contentsize of the textview to limit it.
You could try looking at the following UITextInput Protocol (which the UITextView conforms to) methods
- (NSInteger)characterOffsetOfPosition:(UITextPosition *)position withinRange:(UITextRange *)range
- (UITextRange *)characterRangeByExtendingPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction
- (CGRect)firstRectForRange:(UITextRange *)range
#property(nonatomic, readonly) UITextPosition *endOfDocument
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 *.
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;
}
i want to let the user type in the name of a new file, so there are certain characters i want to prevent entry on. is there a special keyboard i can use or can i disable certain keys on the iphones keyboard.
is the answer to just run a regular expression on the input text and tell the user the filename is invalid (if so what would that regular expression be?)
ANSWER: (or what i ended up doing)
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
BOOL valid;
//if the user has put in a space at the beginning
if ([string isEqualToString:#" "]){
if (range.location == 0){
valid = NO;
}
else{
valid = YES;
}
}
//otherwise test for alpha numeric
else{
NSCharacterSet *alphaSet = [NSCharacterSet alphanumericCharacterSet];
valid = [[string stringByTrimmingCharactersInSet:alphaSet] isEqualToString:#""];
}
//print the warning label
if (valid == NO){
[errorLabel setText:#"Invalid input"];
}
else{
[errorLabel setText:nil];
}
return valid;
}
You can implement the delegate method
For UITextField,
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // return NO to not change text
For UITextview
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
and decide weather to append the entered characters or not.
You can implement the UITextFieldDelegate protocol and use textField:shouldChangeCharactersInRange:replacementString: to watch the text entry and prevent unwanted characters by returning NO.
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.