首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSLayoutConstraint.constant忽略动画

NSLayoutConstraint.constant忽略动画
EN

Stack Overflow用户
提问于 2012-02-29 09:44:01
回答 4查看 8.8K关注 0票数 17

我正在为我的一个应用程序创建一个自动布局友好的拆分视图类。在它的各种功能中,它可以折叠窗格,并且可以以动画的方式折叠窗格,就像你可能见过的NSSplitView一样。

由于我使用了约束,因此我通过在窗格上放置一个required width = (current width)约束来实现这一点,然后以动画方式将约束的常量设置为0:

代码语言:javascript
复制
- (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;
}

这个很好用。不幸的是,以后扩展窗格的效果不是很好。

代码语言:javascript
复制
- (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;
}

如果我插入一些计时代码,我可以看到完成处理程序几乎是立即触发的,在它有时间进行动画之前就消除了约束。在NSAnimationContext上设置持续时间不起作用。

你知道我会做错什么吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-04-01 13:15:35

您必须首先设置完成处理程序,然后才能将消息发送到动画制作代理。否则,似乎在动画开始后设置完成处理程序会立即触发它,并且在动画有时间完成之前常量就会被删除。我刚刚用一段简单的代码检查了这一点:

代码语言:javascript
复制
[NSAnimationContext beginGrouping];
NSAnimationContext.currentContext.duration = animagionDuration;
NSAnimationContext.currentContext.completionHandler = ^{
  [self removeConstraint:collapseConstraint];
};
[collapseConstraint.animator setConstant:expandedHeight];

NSAnimationContext endGrouping;这可以完美地工作,但是如果您在-setConstant:之后设置完成处理程序,动画将没有机会运行。

票数 17
EN

Stack Overflow用户

发布于 2012-03-17 09:03:41

我同意,这很奇怪,很可能是个bug。我肯定会这样报告它,因为据我所知,这应该是可行的。

通过使用NSAnimationContext类方法+runAnimationGroup:completionHandler:而不是beginGroupingendGrouping语句,我能够让它工作:

代码语言:javascript
复制
[NSAnimationContext runAnimationGroup:^(NSAnimationContext* context){
    [constraint.animator setConstant:self.width];   
} completionHandler:^(void){
    [theView removeConstraint:constraint];
    NSLog(@"completed");
}];
票数 13
EN

Stack Overflow用户

发布于 2012-03-15 03:50:48

完成处理程序会立即触发,因为它认为没有任何需要运行的动画。我将检查并确认您创建的动画是否仍附加到视图。默认情况下,CABasicAnimation设置为通过从CAAnimation继承的removedOnCompletion属性在完成时删除自身(默认情况下设置为YES)。

你会想要

代码语言:javascript
复制
anim.removedOnCompletion = NO;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9492467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档