Reputation: 22633
I have an MAAttachedWindow
(subclass of NSWindow
), which contains a blank view (contentView
), and some arbitrary subview (right now an NSImageView
).
On load, I'm attempting to resize the window by 100px vertically, in an animated fashion.
This code block initializes my window and views:
_popoverContentView = [[NSView alloc] initWithFrame: aFrame];
NSImageView *img = [[NSImageView alloc] initWithFrame: aFrame];
[img setImage: [NSImage imageName: "@my_debug_image"]];
[img setAutoresizingMask: NSViewHeighSizable];
[_popoverContentView setAutoresizesSubviews: YES];
[_popoverContentView addSubview: img];
popover = [[MAAttachedWindow alloc] initWithView: _popoverContentView attachedToPoint: aPoint inWindow: nil onSide: MAPositionBottom atDistance: aDist];
And this code block is responsible for the animation:
NSRect newPopoverFrame = popover.frame;
NSRect newPopoverContentViewFrame = _popoverContentView.frame;
newPopoverFrame.size.height += 100;
newPopoverContentViewFrame.size.height += 100;
[_popoverContentView animator] setFrame: newPopoverContentViewFrame];
[[popover animator] setFrame: newPopoverFrame display: YES animate: YES];
Now this all works (almost) as expect, however as shown in this video, the animation is unreliable, shaky, and jumpy. I can't seem to pinpoint what in my code is causing this, or how to go about locking the image view into place.
Upvotes: 2
Views: 1715
Reputation: 46020
I think the problem is that you're using the new(ish) animator proxy to animate the window's frame while also using the much older animate:
parameter of NSWindow
's setFrame:display:animate:
, which uses the old NSViewAnimation
API.
These two animation methods are probably conflicting as they try to animate the window simultaneously using different code paths.
You also need to wrap multiple calls to the animator proxy in [NSAnimationContext beginGrouping]
and [NSAnimationContext endGrouping]
if you wish the animations to be simultaneous.
Try doing this:
[NSAnimationContext beginGrouping];
[_popoverContentView animator] setFrame: newPopoverContentViewFrame];
[[popover animator] setFrame: newPopoverFrame display: YES animate:NO];
[NSAnimationContext endGrouping];
If that doesn't work, you could drop the use of the problematic setFrame:display:animate:
method and just animate the position and size independently:
[NSAnimationContext beginGrouping];
[_popoverContentView animator] setFrame: newPopoverContentViewFrame];
[[popover animator] setFrameOrigin: newPopoverFrame.origin];
[[popover animator] setFrameSize: newPopoverFrame.size];
[NSAnimationContext endGrouping];
The animation context grouping will ensure that everything happens simultaneously.
Upvotes: 1