Jumpy unsynchronized movement with NSViewAnimation
Jumpy unsynchronized movement with NSViewAnimation
- Subject: Jumpy unsynchronized movement with NSViewAnimation
- From: Shamyl Zakariya <email@hidden>
- Date: Thu, 31 May 2007 10:00:27 -0400
Hi,
I'm writing a "help bubble" for providing feedback for custom
NSFormatters I've written, since my formatters require fairly strict
input and I want meaningul feedback to the user to explain what
he'she entered wrong ). So when a user enters something the formatter
doesn't approve of, a little bubble appears beneath the control with
the error message from my formatter.
In addition to this, the bubble shows messages as a stack, where the
newest error is on top, and the old ones are below, in order of
newest to oldest.
Anyway, it works, and it looks pretty nice. So I decided to animate
it ( this is OS X after all, and I wanted to learn about
NSViewAnimation ). The bubble fades in, it resizes smoothly as new
messages come in, the messages themselves smoothly re-order as needed
and so on and so forth. The trouble is, since I'm moving messages as
well as resizing the window, there are some weird synchronization
issues, where the bubble gets drawn *before* the messages have had
their positions set.
It's best described by watching the video below. In it, I'm using a
dummy app I wrote with a few text fields and a custom NSFormatter
which only allows alpha and space characters, so entering punctuation
or numbers will throw a validation error to the control's delegate.
This is then fed to my HelpBubble class. In the demo below I just
entered a few punctuation and numbers and you can see the bubble
grow, and as the messages time out, you can see the bubble shrink. In
the shrink-phase, you can see all the text drops about 1 pixel as the
bubble resizes, and then pops back to the correct position at the end.
http://zakariya.net/shamyl/etc/JumpyAnimation.mov
( Sorry, the video is clearly done with a non-registered version of i-
ShowU -- nice app! )
So, here's how the animation works:
I use an NSViewAnimation to manipulate the window frame and opacity.
The animation delegate propagates the progress to the messages which
are *not* views, but instead draw in the context of the background
view ( which renders the bubble )
- (float) animation: (NSAnimation*) animation valueForProgress:
(NSAnimationProgress) progress
{
progress = Curve( progress, 1.5f );
// update all message tweens
NSEnumerator *enumerator = [_messages objectEnumerator];
HelpBubbleMessageTween *hbmt = nil;
while ( hbmt = [enumerator nextObject] )
{
[hbmt update: progress];
}
return progress;
}
The drawRect method for the background renders the bubble and then
renders each message, who's position was updated above.
I have to assume that the issue here is that the bubble's being drawn
before the message positions are updated, but while I've tried dozens
of ways to synchronize, I haven't had any luck.
For what it's worth, my original implementation had the messages as
actual child views of the window, and I used the NSViewAnimation
which animates the window animate them too, but the animation was
very jerky, with the messages vertically "vibrating" as the window
animated.
Any suggestions as to how I can clean this up would be greatly
appreciated.
email@hidden
"In the same trial, only 16 percent of those who received placebo
sandwiches reported experiencing high levels of deliciousness."
--The Onion
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden