RobertL
RobertL

Reputation: 14924

How to make a idle timer that detects editing activity in a UITextView

I want to allow the user to enter some notes in a UITextView before closing an app. But he/she might not enter anything or he/she might enter some text and then stop and do nothing for a long time. In either of those cases I want to close the UITextView, save some stuff, and exit the app. How do I detect that the user didn't entered anything for a certain number of seconds?

I tried to dispatch a function after a wait time

static int idleSeconds = 8;

self.noteDoneTime = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * idleSeconds);
dispatch_after(self.noteDoneTime, dispatch_get_main_queue(), ^{ [self endNoteRequest]; });

but every time the user changes the text renew the dispatch time:

- (void)textViewDidChange:(UITextView *)textView {
    if (textView == self.noteView) {
        self.noteDoneTime = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * idleSeconds);
    }
}

But that doesn't work because the dispatch time doesn't get updated after it is initially set, so the method 'endNoteRequest' runs even though the user is continuing to edit the text. I think I need to cancel the dispatch request and issue a new one but how can I do that?

Or is there some other approach to an idle timeout that actually works?

Upvotes: 0

Views: 112

Answers (1)

matt
matt

Reputation: 535556

I do something just like this in a game app, where I penalize the user for every 10 seconds that elapses without the user's making any game move. It's like a "shot clock" in basketball, resetting after every shot.

It's easiest to do this with an NSTimer, because now you have an object that you can keep a reference to (e.g. an instance property). When the user types something, you invalidate the timer and set your reference to nil. Now it's gone! Now make a new one and set the reference to it. And so on.

Upvotes: 1

Related Questions