سؤال

When user is typing in UITextfield, and he stops for 2 seconds, the cursor is still on UITextfield, so how we can identify this event? i.e. I want to check the whether the editing is end or not without resigning the first responser from that UITextField. What is the way to do that?

هل كانت مفيدة؟

المحلول

Yes, we can check that! with UITextField delegate, - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

- (void) callMeAfterTwoSeconds {
    NSLog(@"I'll call after two seconds of inactivity!");
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    [NSRunLoop cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(callMeAfterTwoSeconds) withObject:nil afterDelay:2.0];

    return YES;
}

While you're typing (tapping keys from keyboard), it will cancel previous calls for the callMeAfterTwoSeconds function, once you stop, it sets it to call after 2 seconds delay, and yes, it will call after 2 seconds.

Update: Even you can pass that textfield as object to performSelector to know which textfield is inactive, for that your callMeAfterTwoSeconds function will be like,

- (void) callMeAfterTwoSeconds:(UITextField *)textfield {
    if(textfield == txtUserName) {
        NSLog(@"User textfield has NO activity from last two seconds!"); }
}

نصائح أخرى

Go to the connections inspector of your UITextField and connect the "Editing Changed" from the Sent Events list to a predefined IBAction of your choice. Alternatively you can do it programmatically if you are not working with Storyboard.

[youTextField addTarget:self action:@selector(textFieldInputDidChange:) forControlEvents:UIControlEventEditingChanged];

Now the IBAction you've just connected will be fired every time the user changes a character in the UITextField. Create a timer as ivar. Now every time IBAction gets called, start the timer, if it will hit 2sec without being restarted by a new call you know the user hasn't entered/deleted values in the UITextField.

I did this for a searchBar, but I think it works for an UITextField too. The code is in Swift. :)

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
    searchTimer?.invalidate()
    searchTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("search"), userInfo: nil, repeats: false)
}

func search() {
    println("search \(searchBar.text)")
}

I don't think that calling [NSRunLoop cancelPreviousPerformRequestsWithTarget:self] is a good practice.

Instead I would do:

[self.searchTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
//or select the textfield in the storyboard, go to connections inspector and choose the target for 'Editing Changed'


- (IBAction)textFieldDidChange:(id)sender {
    [self performSelector:@selector(editingChanged:) withObject:self.searchTextField.text afterDelay:2.0]; 
}

- (void)editingChanged:(NSString *)text {
    if ([text isEqualToString:self.searchTextField.text]) {
        //do your thing
    }
}

this way the user can type and it will trigger a call to editingChanged:, then you can double check if the value changed meanwhile, and if it didn't then the user stopped typing for 2 seconds.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top