I have an UISearchBar which i implemented in my viewDidLoad: by code.
I have also set the UISearchBarDelegate.
Now i want to restrict the user from entering more than 5 chracter So i implement this delegate method
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSLog(#"shouldChangeTextInRange");
if (searchBar.text.length >= 5)
return NO;
return YES;
}
Its working fine.
The problem is when i typed upto 5 chracters & try to use the keyboard Backspace character, it is not working.
Also now if i pressed Search button in keyboard the searchBarSearchButtonClicked: is not getting called.
I am currently using
XCode version :3.2.5
iOS SDK :4.2
You should do your test on the new text length (then length of the text that you will have if the suggested text change is applied), not the actual text length.
For that, you first need to compute the new text :
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ([text isEqualToString:#"\n"])
return YES; // accept validation button
NSString* newText = [searchBar.text stringByReplacingCharactersInRange:range withString:text];
if (newText.length >= 5)
return NO;
return YES;
}
You can't use backspace because of your code. after typing 5 characters, your searchBar is stuck. Use it instead :
if ([textField.text length] + [string length] - range.length > 5) {
return NO;
}
Related
I have been looking for solutions and found the following piece of code. But I do not know how to use it, unfortunately.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 25) ? NO : YES;
}
Just for testing purposes I set up an IBACTION
-(IBAction)checkIfCorrectLength:(id)sender{
[self textView:myTextView shouldChangeTextInRange: ?? replacementText: ?? ];
}
What do I pass for shouldChangeTextInRange and replacementText ?
Or am I getting it completely wrong ?
Calling textView:shouldChangeTextInRange:replacementText: from checkIfCorrectLength: doesn't make sense. If you want to test the length from multiple methods, factor the test out into its own method:
- (BOOL)isAcceptableTextLength:(NSUInteger)length {
return length <= 25;
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)string {
return [self isAcceptableTextLength:textField.text.length + string.length - range.length];
}
-(IBAction)checkIfCorrectLength:(id)sender{
if (![self isAcceptableTextLength:self.textField.text.length]) {
// do something to make text shorter
}
}
Hi I found and modified the code here. So for xamarin users. try the following:
textView.ShouldChangeText += delegate
{
if(textView.Text.Length > 159) // limit to one sms length
{
return false;
}
return true;
}
You don't call this method yourself, the text view calls it whenever it's about to change its text. Just set the text view's delegate property (e.g. to your view controller) and implement the method there.
If the current object is the delegate of the text view, then you can use the following snippet:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
return weightTextView.text.length + text.length - range.length < 7;
}
This worked for me.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if([text length] == 0)
{
if([textView.text length] != 0)
{
return YES;
}
else {
return NO;
}
}
else if([[textView text] length] > your limit value )
{
return NO;
}
return YES;
}
hi
i am using a series of textfields in a row in my application and my requirement is the textfield should accept only one character.if a user enters second character no action should be performed.
i implemented the delegate method as below
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string{
if ([cellTextField.text length]>=MAXLENGTH && range.length==0) {
textField.text=[cellTextField.text substringToIndex:MAXLENGTH-1];
return NO;
}
else {
return YES;
}
but my requirement is not being filled using the above code.
my next requirement is if a user continues entering a second character, the character should be placed in the consecutive textField(imagine crossword or scramble application). please help me in both scenarios if possible else solution for first requirement is also thankful.
thank you,
dinakar
The following code solved this for me.
Make sure you check for the "\b" (Backspace escape character) so that the user can still erase.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if ([textField.text length] >= MAXLENGTH && ![string isEqualToString:#"\b"])
return NO;
return YES;
}
As far as your second requirement goes it's really not too hard. Just add a few lines of code into the above if-statement:
nextTextField.text = [nextTextField.text stringByAppendingString:string];
This should add whatever text you just typed in to the end of your next text field. You might also want to change the way backspace is handled. Something like:
if ([string isEqualToString:#"\b"])
nextTextField.text = [nextTextField.text substringToIndex:[nextTextField.text length]-1];
Adding that code inside the above if statement as well should allow you to delete the character at the end of the complete string (at the end of the string in the next text field).
EDIT: Here's the code I use to create the field.
titleInput = [[UITextField alloc] initWithFrame:(CGRect){40,145,400,30}];
titleInput.borderStyle = UITextBorderStyleRoundedRect;
titleInput.delegate = self;
[self addSubview:titleInput];
Cheers
if(cellTextField.text.length >= MAXLENGTH)
{
[cellTextField2 becomeFirstResponder]
}
This sets the focus to be the second text field
check in below functions for the number of character in your UITextField;
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
if the number of character in you text field is more than one just return NO;
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(mytextField1 == textField && [mytextField1.text length] >= 1)
{
[mytextField1 becomeFirstResponder];
return NO;
}
else if(mytextField2 == textField && [mytextField2.text length] >= 1)
{
[mytextField3 becomeFirstResponder];
return NO;
}
-------------------------------
-------------------------------
else if(mytextField8 == textField && [mytextField8.text length] >= 1)
{
[mytextField1 becomeFirstResponder];
return NO;
}
return YES;
}
I have a UITextView, the size of which is set through setFrame:CGRectMake(30, 100, 273, 140).
I would like to prevent inserting text that exceeds the size of the TextView.
So I've tried :
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ((textView.contentOffset.y + textView.frame.size.height) < textView.contentSize.height){
return NO;
}
else {
return YES;
}
return YES;
}
The pb is that when the condition is met, I can't use backspace to erase the extra text. The textview is no longer editable. What am I doing wrong here ?
Thanks for your help.
Have you tried something similar to this? I wrote it real quick and haven't tested it out. Let me know if it works. I don't know off the top of my head anything about the fonts, so you'll have to do some reading and adjust the code accordingly, where it says whateveryourfontis
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
NSSTring *newString = [NSString stringWithFormat:#"%#%#", textView.text, text];
CGSize *newSize = [newString sizeWithFont: [UIFont _whateveryourfontis_] constrainedToSize:textView.frame.size];
return (newSize.height > textView.frame.size.height) ? NO : YES;
}
Ok, I think I've found out by myself this time.
I don't know if it is the best solution but it works fine at least.
- (void)textViewDidChange:(UITextView *)uiViewContent{
if ((uiViewContent.contentOffset.y + uiViewContent.frame.size.height) < self.entryTextField2.contentSize.height){
self.entryTextField2.text=[self.entryTextField2.text substringToIndex:[self.entryTextField2.text length] - 1];
}
}
Hope it may help someone...
Mike
By "delete all," I mean what happens when you have a lot of text and you hit backspace for a few seconds, and the text view clears completely. I want to disable that function for my application. How can I do this (if it's even possible/allowed)?
Thanks in advance!!
Link up the delegate outlet of the text view to one of your objects, and put this in it
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
if ( [text length] > 0 ) return YES; // adding = OK
if ( range.length == 1 ) return YES; // removing one = OK
if ( [text length] == range.length ) return NO; // remove all != OK
return YES; // all else is ok (this includes autocorrection, cut/paste things)
}
I want to compare a string with user input character by character. e.g. I want to let user input "I have an apple." and compare the input with this string to see if his input is correct. When he input a wrong character, iphone will vibrate to inform him immediately. The problem is that I find some characters like the space will call the delegate method twice- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
When I press the space key, the first time I compare the text with the ' ', the result will show me that they're the same character. But after that, I have to advance the index of string character to the next. And the second time the delegate method is called, iphone will vibrate. Any ideas about how to solve this problem?
Here is my code:
strText = #"I have an apple.";
index = 0;
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSRange rg = {index, 1};
NSString *correctChar = [strText substringWithRange:rg];
if([text isEqualToString:correctChar])
{
index++;
if(index == [strText length])
{
// inform the user that all of his input is correct
}
else
{
// tell the user that he has index(the number of correct characters) characters correct
}
}
else {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
return NO;
}
return YES;
}
try this
- (void)textViewDidChange:(UITextView *)textView{
if(![myStringToCompareWith hasPrefix:textView.text]){
//call vibrate here
}
}
Building on Morion's suggestion of using hasPrefix:, I think this is the solution that you are looking for:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
// create final version of textView after the current text has been inserted
NSMutableString *updatedText = [NSMutableString stringWithString:textView.text];
[updatedText insertString:text atIndex:range.location];
if(![strTxt hasPrefix:updatedText]){
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
return NO;
}
return YES;
}