views:

426

answers:

2

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;
}

+1  A: 

try this

- (void)textViewDidChange:(UITextView *)textView{
   if(![myStringToCompareWith hasPrefix:textView.text]){
    //call vibrate here
   }
}
Morion
Thanks. I solve my problem by replace my else block with your code and after vibrate I delete the wrong character user has entered.
iPhoney
I just want to understand the reason of the problem. Do you know the reason why the space key just generate an address instead of a blank character for the delegate method? And why the shouldChangeTextInRange method is called twice?
iPhoney
A: 

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;
}
gerry3
I tested your code and find that when I type the space key, the insertString method will throw an exception. It looks like the space key will not generate a string for the delegate method but an address.
iPhoney
It worked fine for me and I used your exact string (with spaces). Are you sure it's the insertString that is failing?
gerry3