UIView动画闪烁自动反转

bri*_*dge 7 animation uikit

我正在尝试将指示器设置为空表单字段的动画,因此我使用下面的方法设置动画到位置,反转动画,然后重复.在模拟器中,这工作正常,在我的3GS上,看起来在调用完成块时有一个闪烁.指示器在中间位置短暂显示,而不是在其原点返回.

有关为什么会发生这种情况的任何想法?谢谢.

- (void)bounceFormIndicator {
    if (formIndicator.superview == nil) {
        return;
    }

    int bounceDistance = 24;

    [UIView animateWithDuration:0.6 
                          delay:0 
                        options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                        CGRect indicatorFrame = formIndicator.frame;
                        indicatorFrame.origin.x += bounceDistance;
                        formIndicator.frame = indicatorFrame;
                     }completion:^(BOOL finished){
                        CGRect indicatorFrame = formIndicator.frame;
                        indicatorFrame.origin.x -= bounceDistance;
                        formIndicator.frame = indicatorFrame;
                        [self bounceFormIndicator];
                     }];
}
Run Code Online (Sandbox Code Playgroud)

C4 *_*vis 13

我有同样的问题,并去Apple DTS帮助解决方法.

根据DTS,这种"闪烁"效果或快照效应是预期的行为......我认为我的项目已经做了很长时间了.

特别是这种方式是因为文档说明了

UIViewAnimationOptionAutoreverse向后和向前运行动画.

必须与UIViewAnimationOptionRepeat选项结合使用.

为了让闪烁消失,我不得不做两件事.

我的实现是动态的,所以你可能不需要实现第一步,但我会将它保留在这里仅供参考.

首先,我检查是否UIViewAnimationOptionAutoreverse是我要传递给动画的选项的一部分,而UIViewAnimationOptionRepeat 不是 ......如果是这样,我通过添加如下行来从选项中删除它:

animationOptions &= ~UIViewAnimationOptionAutoreverse;
Run Code Online (Sandbox Code Playgroud)

为了创建反转动画而不重复,我添加了一个相反的UIView动画作为我的完成块.如果是UIViewAnimationOptionCurveEaseIn或者UIViewAnimationOptionCurveEaseOut...... 我也放弃了缓和

我项目的代码如下:

从对象的animationOptions中剥离自动反转选项的语句:

if ((animationOptions & AUTOREVERSE) == AUTOREVERSE) {
    self.shouldAutoreverse = YES;
    animationOptions &= ~AUTOREVERSE;
}
Run Code Online (Sandbox Code Playgroud)

处理动画的重写属性设置器的示例:

-(void)setCenter:(CGPoint)center {
    CGPoint oldCenter = CGPointMake(self.center.x, self.center.y);

    void (^animationBlock) (void) = ^ { super.center = center; };
    void (^completionBlock) (BOOL) = nil;

    BOOL animationShouldNotRepeat = (self.animationOptions & REPEAT) !=  REPEAT;
    if(self.shouldAutoreverse && animationShouldNotRepeat) {
        completionBlock = ^ (BOOL animationIsComplete) {
            [self autoreverseAnimation:^ { super.center = oldCenter;}];
        };
    }
    [self animateWithBlock:animationBlock completion:completionBlock];
}
Run Code Online (Sandbox Code Playgroud)

在没有重复的情况下,在反转的情况下需要完成方法:

-(void)autoreverseAnimation:(void (^)(void))animationBlock {
        C4AnimationOptions autoreverseOptions = BEGINCURRENT;
        if((self.animationOptions & LINEAR) == LINEAR) autoreverseOptions |= LINEAR;
        else if((self.animationOptions & EASEIN) == EASEIN) autoreverseOptions |= EASEOUT;
        else if((self.animationOptions & EASEOUT) == EASEOUT) autoreverseOptions |= EASEIN;

        [UIView animateWithDuration:self.animationDuration
                              delay:0
                            options:autoreverseOptions
                         animations:animationBlock
                         completion:nil];
}
Run Code Online (Sandbox Code Playgroud)