微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在iOS中动画文本内容 – 等同于Android ValueAnimator

我正在使用iOS 7应用程序,并希望动画更改UILabel的内容.我不想做任何图形动画,如淡化旧内容/淡入新内容.因此,iOS提供的所有标准动画功能(如图层动画或动画块)无法使用(至少我认为).

假设UILabel显示“200 V”的仪表值,此文本应更改为“400 V”.文本不应该只是从“200 V”跳到“400 V”,而应该使用一些缓动功能计数:“200 V”,“220 V”,“240 V”…“390 V”,“395 V“…”400 V“

Android中可以使用ValueAnimator轻松解决

ValueAnimator animation = ValueAnimator.ofFloat(0f,1f);
animation.setInterpolation(new EaSEOutInterpolator());
animation.setDuration(2500);
animation.setStartDelay(500);

animation.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpate(ValueAnimator animator) {
        float currentValue = animator.getAnimatedValue.floatValue();
        label1.setText(String.format("%.2",fromValue1 + ((tovalue1 - fromValue1) * currentValue)));
        label2.setText(String.format("%.2",fromValue2 + ((tovalue2 - fromValue2) * currentValue)));
    ...
    }
});
animation.start();

iOS还有这样的事情吗?我发现不同的解决方案,但它们都很旧(2010/11),并且最终都使用NSTimer和自己的缓动功能手动实现这个行为.

没有问题,可以自己实现这一点,但这将是相当麻烦,不是非常优雅.那么在iOS中有没有什么可以解决这个问题呢,还是至少有方便的第三方实现?

非常感谢你!

解决方法

因为我没有找到定制的解决方案,我创建了我自己的:一个简单的动画师类,处理轻松:
// MyValueAnimation.h
typedef void (^MyAnimationBlock)(double animationValue);

@interface MyValueAnimation : NSObject

- (void)startAnimation:(MyAnimationBlock)animationBlock runtime:(NSUInteger)runtime delay:(NSUInteger)delay;

@end


// MyValueAnimation.m
#import "MyValueAnimation.h"

// Number of seconds between each animation step
#define kStepSize 0.05

@interface MyValueAnimation () {
    NSTimer *timer;            
    NSUInteger totalRunTime;    // Total duration of the animation (delay not included)
    NSUInteger currentRuntime;  // Time the animation is already running
    MyAnimationBlock animationBlock;
}
@end

@implementation MyValueAnimation

- (void)startAnimation:(MyAnimationBlock)block runtime:(NSUInteger)runtime delay:(NSUInteger)delay {
    if (timer != nil)
        [timer invalidate];

    timer = nil;
    totalRunTime = runtime;
    animationBlock = block;
    currentRuntime = 0;

    if (block != nil) {
        if (delay > 0) {
            // Wait to delay the start. Convert delay from millis to seconds
            double delaySeconds = (double)delay / 1000.0;
            timer = [NSTimer scheduledTimerWithTimeInterval:delaySeconds target:self selector:@selector(delayTick:) userInfo:nil repeats:false];
        } else {
            // Run the animation
            timer = [NSTimer scheduledTimerWithTimeInterval:kStepSize target:self selector:@selector(animationTick:) userInfo:nil repeats:true];
        }
    }
}

- (void)delayTick:(NSTimer *)delayTimer {
    // End of delay -> run animation
    [delayTimer invalidate];
    timer = [NSTimer scheduledTimerWithTimeInterval:kStepSize target:self selector:@selector(animationTick:) userInfo:nil repeats:true];
}

- (void)animationTick:(NSTimer *)animationTimer {
    NSUInteger step = 1000 * kStepSize;  // step size/length in milli seconds
    currentRuntime += step;
    double progress = MIN((double)currentRuntime / (double)totalRunTime,1.0);

    // Progress is a value between 0 and 1. The easing function maps this
    // to the animationValue which is than used inside the animationBlock
    // to calculate the current value of the animiation
    double animationValue = [self customEaSEOut:progress];

    if (animationBlock != nil)
        animationBlock(animationValue);

    if (progress >= 1.0) {
        // Animation complete
        [timer invalidate];
        timer = nil;
    }        
}

- (double)customEaSEOut:(double)t {
    // Use any easing function you like to animate your values...
    // http://rechneronline.de/function-graphs/
    // http://sol.gfxile.net/interpolation/
    return (1 - pow(1-t,2));
}

@end 


// =============================================================

// Some code using the animation
- (void)animateValueFrom:(double)fromValue to:(double)tovalue {
    if (valueAnimation == nil)
        valueAnimation = [[MyValueAnimation alloc] init];

    MyAnimationBlock animationBlock = ^(double animationValue) {
        double currentValue = fromValue + ((tovalue - fromValue) * animationValue);

        someLabel.text = [Nsstring stringWithFormat:"%dV",currentValue];        
    };

    [valueAnimation startAnimation:animationBlock runtime:1500 delay:500];
}

也许不是最漂亮的解决方案,但它的作品:-)

原文地址:https://www.jb51.cc/iOS/335918.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐