FROM : Shawn Erickson
DATE : Fri Apr 08 21:31:26 2005
On Apr 8, 2005, at 11:59 AM, Keith Blount wrote:
> Hello,
>
> I need to update part of my display whenever the user
> finishes typing in an NSTextView. According to the
> docs,the best way to do this is using
> NSNotificationQueue. I tried the following in an
> NSTextView subclass:
>
> - (void)didChangeText
> {
> [super didChangeText];
>
> [[NSNotificationQueue defaultQueue]
> enqueueNotification:[NSNotification
> notificationWithName:_KBTextViewDidFinishTypingNotification
> object:self] postingStyle:NSPostWhenIdle
> coalesceMask:NSNotificationCoalescingOnName
> forModes:nil];
> }
>
> I registered self as an observer of
> _KBTextViewDidFinishTypingNotification. However, the
> notification is still being sent on every letter typed
> (typing fast), not when typing ends or pauses. Does
> anybody know what I am doing wrong, or the best way of
> coalescing notifications so that they are only sent
> upon the user finishing typing?
It will only coalesce if a notification is still in the queue at the
time another is enqueued.
Every time you hit a key an event comes into NSApplication via its
runloop and it kicks of handlers as needed. Depending on what is taking
place the handling of the key press may be rather fast and return the
runloop to an idle state (no other non-idle time event is left to
service). So it will then likely process your idle time notification.
In other words the window of time to coalesce is can be small even more
so since you only send your notification in response to the results of
the handling of a key press.
What do you mean by "upon the user finishing typing"? How do think that
should be determined?
Based on time since last key press, finished editing in a control, etc.
If you want your "did finish typing" handler(s) to be called after a
certain amount of time then consider using NSTimer to schedule a
callback X amount of time in the future when didChangeText gets called,
invalidating any timer that may have been scheduled on a prior call to
didChangeText. So if didChangeText isn't called within that window of
time then the timer won't get rescheduled and it will fire and the
timer callback could send the notification or directly do what you
needed done.
Or possible better yet you could utilize NSObject's
performSelector:withObject:afterDelay: and
cancelPreviousPerformRequestsWithTarget:selector:object: to manage this
instead having to manage a timer yourself. In other words something
like...
NSNotification notification = [NSNotification
notificationWithName:_KBTextViewDidFinishTypingNotification
object:self];
NSNotificationCenter dq = [NSNotificationCenter defaultCenter];
[NSObject cancelPreviousPerformRequestsWithTarget:dq
selector:@selector(postNotification:)
object:notifcation];
[dq performSelector:@selector(postNotification:)
withObject:notifcation afterDelay:0.5];
-Shawn
DATE : Fri Apr 08 21:31:26 2005
On Apr 8, 2005, at 11:59 AM, Keith Blount wrote:
> Hello,
>
> I need to update part of my display whenever the user
> finishes typing in an NSTextView. According to the
> docs,the best way to do this is using
> NSNotificationQueue. I tried the following in an
> NSTextView subclass:
>
> - (void)didChangeText
> {
> [super didChangeText];
>
> [[NSNotificationQueue defaultQueue]
> enqueueNotification:[NSNotification
> notificationWithName:_KBTextViewDidFinishTypingNotification
> object:self] postingStyle:NSPostWhenIdle
> coalesceMask:NSNotificationCoalescingOnName
> forModes:nil];
> }
>
> I registered self as an observer of
> _KBTextViewDidFinishTypingNotification. However, the
> notification is still being sent on every letter typed
> (typing fast), not when typing ends or pauses. Does
> anybody know what I am doing wrong, or the best way of
> coalescing notifications so that they are only sent
> upon the user finishing typing?
It will only coalesce if a notification is still in the queue at the
time another is enqueued.
Every time you hit a key an event comes into NSApplication via its
runloop and it kicks of handlers as needed. Depending on what is taking
place the handling of the key press may be rather fast and return the
runloop to an idle state (no other non-idle time event is left to
service). So it will then likely process your idle time notification.
In other words the window of time to coalesce is can be small even more
so since you only send your notification in response to the results of
the handling of a key press.
What do you mean by "upon the user finishing typing"? How do think that
should be determined?
Based on time since last key press, finished editing in a control, etc.
If you want your "did finish typing" handler(s) to be called after a
certain amount of time then consider using NSTimer to schedule a
callback X amount of time in the future when didChangeText gets called,
invalidating any timer that may have been scheduled on a prior call to
didChangeText. So if didChangeText isn't called within that window of
time then the timer won't get rescheduled and it will fire and the
timer callback could send the notification or directly do what you
needed done.
Or possible better yet you could utilize NSObject's
performSelector:withObject:afterDelay: and
cancelPreviousPerformRequestsWithTarget:selector:object: to manage this
instead having to manage a timer yourself. In other words something
like...
NSNotification notification = [NSNotification
notificationWithName:_KBTextViewDidFinishTypingNotification
object:self];
NSNotificationCenter dq = [NSNotificationCenter defaultCenter];
[NSObject cancelPreviousPerformRequestsWithTarget:dq
selector:@selector(postNotification:)
object:notifcation];
[dq performSelector:@selector(postNotification:)
withObject:notifcation afterDelay:0.5];
-Shawn
| Related mails | Author | Date |
|---|---|---|
| Keith Blount | Apr 8, 20:59 | |
| Shawn Erickson | Apr 8, 21:31 |






Cocoa mail archive

