NSView 调整大小时不稳定

发布于 2024-12-04 13:56:16 字数 1249 浏览 1 评论 0原文

我有一个 MAAttachedWindowNSWindow 的子类),其中包含一个空白视图 (contentView) 和一些任意子视图(现在是一个 >NSImageView)。 加载时,我尝试以动画方式将窗口大小垂直调整 100 像素。

此代码块初始化我的窗口和视图:

_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];

此代码块负责动画:

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];

现在这一切(几乎)按预期工作,但是如 此视频,动画不可靠、摇晃且跳跃。我似乎无法确定代码中的原因是什么,或者如何将图像视图锁定到位。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寂寞美少年 2024-12-11 13:56:16

我认为问题在于您正在使用新的动画代理来为窗口的框架设置动画,同时还使用 NSWindowanimate: 参数code>setFrame:display:animate:,它使用旧的 NSViewAnimation API。

这两种动画方法可能会发生冲突,因为它们尝试使用不同的代码路径同时对窗口进行动画处理。

如果您希望动画同时进行,您还需要将对动画代理的多个调用包装在 [NSAnimationContext beginGrouping][NSAnimationContext endGrouping] 中。

尝试这样做:

[NSAnimationContext beginGrouping];
[_popoverContentView animator] setFrame: newPopoverContentViewFrame];
[[popover animator] setFrame: newPopoverFrame display: YES animate:NO];
[NSAnimationContext endGrouping];

如果这不起作用,您可以放弃使用有问题的 setFrame:display:animate: 方法,而只是独立地设置位置和大小的动画:

[NSAnimationContext beginGrouping];
[_popoverContentView animator] setFrame: newPopoverContentViewFrame];
[[popover animator] setFrameOrigin: newPopoverFrame.origin];
[[popover animator] setFrameSize: newPopoverFrame.size];
[NSAnimationContext endGrouping];

动画上下文分组将确保一切同时发生。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文