Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 带有约束的动画立即完成_Ios_Core Animation_Nslayoutconstraint - Fatal编程技术网

Ios 带有约束的动画立即完成

Ios 带有约束的动画立即完成,ios,core-animation,nslayoutconstraint,Ios,Core Animation,Nslayoutconstraint,我有一些动画,我正试图转换为约束。其背后的想法是,当出现错误时,登录提示会反弹 我的方法是,视图控制器上的所有内容都在bounceView中,而bounceView本身也在主视图中 bounceView使用居中约束和前导空间约束绑定到主视图。为了在设计时使布局明确,还存在前导空间和顶部空间约束。不过,这些只是占位符,在运行时会替换为等高/等宽约束 没有其他约束绑定到主视图 现在,一些细节 我使用这些约束来定义反弹: enum {animationDone, bounceStart, bounce

我有一些动画,我正试图转换为约束。其背后的想法是,当出现错误时,登录提示会反弹

我的方法是,视图控制器上的所有内容都在bounceView中,而bounceView本身也在主视图中

bounceView使用居中约束和前导空间约束绑定到主视图。为了在设计时使布局明确,还存在前导空间和顶部空间约束。不过,这些只是占位符,在运行时会替换为等高/等宽约束

没有其他约束绑定到主视图

现在,一些细节

我使用这些约束来定义反弹:

enum {animationDone, bounceStart, bounceLeft, bounceRight, bounceReturn};
static const NSTimeInterval BounceDuration = 20.0;
static const int NumberOfBounces = 3;
static const CGFloat BounceDistance = 16.0f;
(20秒的延迟通常要短得多;我将其倾斜以证明这不起作用。)

额外的运行时约束设置如下:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_bounceView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_bounceView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
}
我使用以下代码启动动画:

_animateCount = NumberOfBounces;
_animateStage = bounceStart;
[self animationStep];
实际代码非常简单:

- (void)animationStep {
    CGFloat bounceTo = 0;
    BOOL half = NO;
    switch (_animateStage) {
        case bounceStart:
            _animateStage = bounceLeft;
            bounceTo = -BounceDistance;
            half = YES;
            break;
        case bounceLeft:
            _animateStage = bounceRight;
            bounceTo = BounceDistance;
            break;
        case bounceRight:
            if ( --_animateCount > 0 ) {
                _animateStage = bounceLeft;
                bounceTo = -BounceDistance;
            } else {
                _animateStage = bounceReturn;
                bounceTo = 0;
            }
            break;
        case bounceReturn:
            half = YES;
            _animateStage = animationDone;
            break;
    }

    BOOL finishedAnimation = ( ( _animateStage == animationDone ) || ( self.view == nil ) );

    if ( !finishedAnimation ) {
        [_bounceView layoutIfNeeded];
        _centerX.constant = bounceTo;
        [_bounceView setNeedsUpdateConstraints];

        NSTimeInterval duration = half ? BounceDuration / 2.0f : BounceDuration;
        [UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            NSLog(@"Bouncing to %f over %f seconds.", bounceTo, duration);
            [_bounceView layoutIfNeeded];
        } completion:^(BOOL finished) {
            [self animationStep];
        }];
    }
}
然而,这一切都是立即完成的:

2013-10-29 10:59:43.852 App[9151:907] Bouncing to -16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.864 App[9151:907] Bouncing to 16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.865 App[9151:907] Bouncing to -16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.866 App[9151:907] Bouncing to 16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.866 App[9151:907] Bouncing to -16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.867 App[9151:907] Bouncing to 16.000000 over 20.000000 seconds.
2013-10-29 10:59:43.867 App[9151:907] Bouncing to 0.000000 over 20.000000 seconds.
有什么想法吗

更新

对于后代来说,这是由于在子视图上调用
setNeedsUpdateConstraints
layoutifneed
造成的。尽管苹果的文档中暗示了其他情况,但您需要在superview上调用它。我在下面的回答中对此进行了详细说明

然而,我接受了@nielsbot的答案。尽管不是我问题的直接答案,但这是一个比修复我试图做的事情更好的解决方案。

有帮助吗


我知道你在动画中使用的是比那篇文章中简单的更细粒度的控制方法,但是我认为基本的
setNeedsUpdateLayoutConstraints
和后续的
layoutIfNeeded
调用在这里仍然适用。

您必须在superview上同时调用
setNeedsUpdateConstraints
layoutIfNeeded
。尽管苹果的文档中说
layoutifneedd
将爬过视图,但情况似乎并非如此

为便于将来参考,需要苹果公司当前的
layoutifn文档

使用此方法可以在绘制之前强制子视图的布局。从接收器开始,只要SuperView需要布局,该方法就会向上遍历视图层次结构。然后它把整个树都放在祖先的下面。因此,调用此方法可能会强制整个视图层次结构的布局


不能使用核心动画临时设置视图的动画吗

请看我的回答:

基本上,在要设置动画的视图上,获取其层并向其添加动画。如果通过设置层变换的动画来执行此操作,则不会更改视图的大小或位置,也不会触发布局循环

CAKeyframeAnimation * anim = [ CAKeyframeAnimation animationWithKeyPath:@"transform" ] ;
anim.values = @[ [ NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-5.0f, 0.0f, 0.0f) ], [ NSValue valueWithCATransform3D:CATransform3DMakeTranslation(5.0f, 0.0f, 0.0f) ] ] ;
anim.autoreverses = YES ;
anim.repeatCount = 2.0f ;
anim.duration = 0.07f ;

[ viewToShake.layer addAnimation:anim forKey:nil ] ;

我想这就是我正在做的:
[\u bounceView setNeedsUpdateConstraints]
在块外,然后
[\u bounceView LayoutFeeded]
在块内。是的,我已经玩了20分钟左右,得到了和你一样的行为(即时转换)。如果我有什么想法的话,我会回电的。我不认为这是我现在需要的,但我想我需要在一个小时后从另一个角度来看这个把戏。谢谢。:)你想要不同的效果吗?你这样做需要更多的工作和更多的CPU时间(可能可以忽略不计),最重要的是你正在对抗约束布局系统。如果你坚持走这条路线,也许你可以在制作动画时暂时禁用约束。实际上,你可能会得到最好的答案,即使它不是最直接的。我要试试这个。今天晚些时候可能会接受。是的。你赢了。我希望你不介意,但我会把你的代码复制粘贴到这里,以便将来搜索。