动画自动布局与NSPopover contentSize更改同时更改

时间:2013-02-09 00:51:44

标签: cocoa animation autolayout nspopover

我试图在popover中重现可导航视图的iTunes 11行为。我似乎无法找到一种方法来让我的动画在弹出的contentSize更改发生的同时发生。

我的基本设置是一个自定义视图子类MyPopoverNavigationView,带有两个子视图:我希望popover在其间导航的旧视图和新视图。 popover的contentViewController有一个MyPopoverNavigationView实例作为其view。我这样做:

// Configure constraints how I want them to show the new popover view
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *ctx) {
    [ctx setDuration:0.25];
    [ctx setAllowsImplicitAnimation:YES];
    [self layoutSubtreeIfNeeded];
} completionHandler:nil];

据我所知,从Auto Layout WWDC 2012视频中,这是一种建议的方法,可以在约束更改的情况下对视图帧的更改进行动画处理。它有效,但动画分两个阶段进行:

  • 首先,popover的contentSize将更改以适应我要移动的新视图(之前该视图变为可见,因此它会部分模糊现有内容)。
  • 其次,视图按照我的预期进行动画处理,以便我安装的约束系统得到满足。

通过设置一些断点,看起来-layoutSubtreeIfNeeded最终会在名为_fromConstraintsSetWindowFrame:的popover上调用一个私有方法,它会在我的动画组外部执行popover大小的动画。我的上下文的持续时间不受尊重,我的动画在弹出框的大小更改完成后才会发生。

如何让我的观点与弹出窗口的大小变化一起动画?

2 个答案:

答案 0 :(得分:4)

结果诀窍是明确设置动画和完成块的popover的contentSize属性之外。我sample GitHub project汇总的相关摘要看起来像是:

// Configure constraints for post-navigation view layout
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *ctx) {
    [ctx setDuration:0.25];
    [ctx setAllowsImplicitAnimation:YES];
    [self layoutSubtreeIfNeeded];
} completionHandler:^{
    // Tear down some leftover constraints from before the transition
}];

// Explicitly set popover's contentSize so its animation happens simultaneously
containingPopover.contentSize = postTransitionView.frame.size;

答案 1 :(得分:0)

这对Sierra来说很好用:

let deltaHeight = 8 
let contentSize = popover.contentSize  
NSAnimationContext.runAnimationGroup({ (context) -> Void in
    context.allowsImplicitAnimation = true
    popover.contentSize = NSSize(width: contentSize.width, height: contentSize.height+deltaHeight)
})