在iOS中设置文本内容动画-相当于Android ValueAnimator
我正在使用iOS 7+应用程序,希望更改UILabel的内容。我不想做任何图形动画,比如淡出旧内容/淡入新内容。因此,iOS提供的所有标准动画功能(如层动画或动画块)都无法使用(至少我认为是这样) 假设UILabel显示一些仪表值,如“200 V”,则该文本应更改为“400 V”。文本不应该仅仅从“200 V”跳到“400 V”,而应该使用一些缓和功能来计算:“200 V”、“220 V”、“240 V”。。。“390伏”,“395伏”。。。“400伏” 在Android中,可以使用ValueAnimator轻松解决:在iOS中设置文本内容动画-相当于Android ValueAnimator,ios,animation,Ios,Animation,我正在使用iOS 7+应用程序,希望更改UILabel的内容。我不想做任何图形动画,比如淡出旧内容/淡入新内容。因此,iOS提供的所有标准动画功能(如层动画或动画块)都无法使用(至少我认为是这样) 假设UILabel显示一些仪表值,如“200 V”,则该文本应更改为“400 V”。文本不应该仅仅从“200 V”跳到“400 V”,而应该使用一些缓和功能来计算:“200 V”、“220 V”、“240 V”。。。“390伏”,“395伏”。。。“400伏” 在Android中,可以使用ValueA
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中是否有内置的解决方案,或者是否至少有方便的第三方实现
多谢各位 因为我没有找到适合的解决方案,所以我创建了自己的解决方案:一个简单的Animator类,用于处理动画:
// 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];
}
也许不是最漂亮的解决方案,但它是有效的:-)我知道一个解决方案,但它用于快速迭代,因为最终迭代可以跳过值(如果搜索速度慢,看起来并不漂亮),但决策简单而简短,不能从架构实现(但如果有必要,可以更正)中获得最美的结果
- (void)someAction
{
[self animateValue:0 toValue:1111 withStep:7 andIntervalSpeed:5];
}
-(void)animateValue:(int)value toValue:(int)toValue withStep:(int)step andIntervalSpeed:(int64_t)intervalSpeed
{
self.currentValue = value; // @property (nonatomic) int currentValue;
NSUInteger numberofIteration = (toValue - value)/step;
int64_t interval = 0.0;
for (NSUInteger i = 0; i < numberofIteration; i++) {
dispatch_time_t start = DISPATCH_TIME_NOW;
interval += intervalSpeed;
dispatch_after(dispatch_time(start, interval * USEC_PER_SEC), dispatch_get_main_queue(), ^{
if (((toValue - value)%step != 0) && (i == (numberofIteration-1)))
{
self.currentValue = toValue;
}
else
{
self.currentValue+= step;
}
NSLog(@"%d",self.currentValue);
self.someLabel.text = [NSString stringWithFormat:@"%d",self.currentValue];
});
}
}
-(void)someAction
{
[自动画评估值:0到值:1111,步骤:7,间隔速度:5];
}
-(void)animateValue:(int)value to value:(int)to value with step:(int)step和intervalSpeed:(int 64_t)intervalSpeed
{
self.currentValue=value;//@property(非原子)int-currentValue;
NSUInteger numberofIteration=(toValue-value)/步;
int64_t间隔=0.0;
对于(i=0;i
如果您已成功找到解决方案,请发布。@TommieC。我用了一个环,但它不是很平滑,看起来很滞后。你找到解决方案了吗?@JayVDiyk-还没有找到简单的iOS解决方案,但我确实从核心动画师团队那里得到了这个示例:在终端窗口中,从bitbucket克隆项目~git clone看一看,我想这回答了你的问题。太棒了!但是我猜toble
第行-(void)animatevaluefom:(double)fromValue to:(toble)toValue
是一种特殊的数据结构吗P或者只是一个替身:)你不知道什么是托布尔!?你是什么样的开发者?你真丢脸!它是一种特殊的double
,只有最优秀的开发人员知道。为了让其他人(包括你)更容易理解,我将其更改为普通的双精度:-P