NSLayoutConstraint.constant忽略动画 [英] NSLayoutConstraint.constant ignoring animation

查看:336
本文介绍了NSLayoutConstraint.constant忽略动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的应用程序之一创建一个自动版式友好拆分视图类。在它的各种功能是它可以折叠面板,并可以动画的崩溃,就像你可能已经看到NSSplitView做的。

I'm creating an autolayout-friendly split view class for one of my applications. Among its various features is that it can collapse panes, and can animate their collapse, much as you might have seen NSSplitView do.

由于我使用的限制,我被放置所需的宽度=(当前宽度)约束的窗格,然后设置约束的常数0以动画方式实现这一目标:

Since I'm using constraints, I'm achieving this by placing a required width = (current width) constraint on the pane, and then setting the constraint's constant to 0 in an animated fashion:

- (NSLayoutConstraint*)newHiddenConstraintAnimated:(BOOL)animated {
    NSLayoutConstraint * constraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:NSWidth(self.view.frame)];
    constraint.priority = NSLayoutPriorityRequired;

    CABasicAnimation * anim = [CABasicAnimation animation];
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    anim.duration = 0.2;
    constraint.animations = [NSDictionary dictionaryWithObject:anim forKey:@"constant"];

    [self.view addConstraint:constraint];

    [(animated ? constraint.animator : constraint) setConstant:0.0];

    return constraint;
}

本精美的作品。不幸的是,后来扩大窗格不那么幸运。

This works beautifully. Unfortunately, expanding the pane later does not fare so well.

- (void)removeHiddenConstraintAnimated:(BOOL)animated {
    if(!animated) {
        [self.view removeConstraint:self.hiddenConstraint];
    }
    else {
        NSLayoutConstraint * constraint = self.hiddenConstraint;
        NSView * theView = self.view;

        [NSAnimationContext beginGrouping];

        [constraint.animator setConstant:self.width];

        [NSAnimationContext currentContext].completionHandler = ^{
            [theView removeConstraint:constraint];
        };

        [NSAnimationContext endGrouping];
    }

    self.hiddenConstraint = nil;
}

如果我插入一些时间code,我可以看到,完成处理火灾几乎是瞬间,删除约束它有时间才动画。设置在NSAnimationContext的持续时间没有任何效果。

If I insert some timing code, I can see that the completion handler fires almost instantly, removing the constraint before it has time to animate. Setting a duration on the NSAnimationContext has no effect.

任何想法,我可以做什么错在这里?

Any idea what I could be doing wrong here?

推荐答案

您必须首先设置完成处理,然后才将消息发送到动画代理。否则,似乎设置完成处理程序的动画启动之后将立即触发它与该动画的时间来完成之前的恒定被除去。
我刚才选中该用一块简单的code的:

You have to first set the completion handler and only then send the message to the animator proxy. Otherwise, it seems that setting the completion handler after the animation started fires it immediately and the constant is removed before the animation has time to finish. I have just checked this with a piece of simple code:

    [NSAnimationContext beginGrouping];
    NSAnimationContext.currentContext.duration = animagionDuration;
    NSAnimationContext.currentContext.completionHandler = ^{[self removeConstraint:collapseConstraint];};
    [collapseConstraint.animator setConstant:expandedHeight];
    [NSAnimationContext endGrouping];

这完美的作品,但如果你设置完成后,处理程序 -setConstant:,动画没有机会运行

This works perfectly, but if you set completion handler after -setConstant:, the animation does not have a chance to run.

这篇关于NSLayoutConstraint.constant忽略动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆