使用NSTimer做匀速动画和变速动画
NSTimer是一个计时器类,用于定时向指定对象发送消息,本案例使用NSTimer制作飞机匀速飞行和减速飞行的效果,如图-1所示:
图-1
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和Button控件,在右边栏的检查器中设置ImageView的显示图片,并将ImageView设置为TRViewController的属性imageView,将Button关联成TRViewController的方法start。
其次TRViewController中定义两个属性CGPoint类型的startPoint,用于记录飞机的开始点,NSUInteger类型的count用于计数。
然后实现start方法,在该方法创建一个计时器,每隔1/30秒重复调用方法run:。
最后实现方法run:,在该方法根据startPoint、count的计数、动画时长和帧率计算出每次调用该方法飞机移动的距离,如果是匀速运动每次移动的距离是相同的,如果是减速运动每次移动的距离则逐步减小。
实现此案例需要按照如下步骤进行。
步骤一:搭建StoryBoard界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和Button控件,在右边栏的检查器中设置ImageView的显示图片,并将ImageView设置为TRViewController的属性imageView,将Button关联成TRViewController的方法start,代码如下所示:
- @interface TRViewController ()
- @property (weak, nonatomic) IBOutlet UIImageView *imageView;
- @end
步骤二:创建计时器
首先在TRViewController中定义两个属性CGPoint类型的startPoint,用于记录飞机的开始点,NSUInteger类型的count用于计数,代码如下所示:
- @interface TRViewController ()
- @property (weak, nonatomic) IBOutlet UIImageView *aircraftView;
- @property (nonatomic) CGPoint startPoint;
- @property (nonatomic) NSUInteger count;
- @end
然后实现start方法,在该方法创建一个计时器,每隔1/30秒重复调用方法run:,代码如下所示:
- - (IBAction)start
- {
- self.startPoint = self.aircraftView.center;//记录开始位置
- [NSTimer scheduledTimerWithTimeInterval:1/FPS target:self selector:@selector(run:) userInfo:nil repeats:YES];
- }
步骤三:实现run:方法
首先定义两个宏FPS用来表示帧率,DURATION用来表示动画时长,根据count的计数、动画时长和帧率计算出每次调用该方法飞机移动的距离,如果是匀速运动每次移动的距离是相同的,代码如下所示:
- #define FPS 30.0 //帧率
- #define DURATION 3//动画时长
- - (void)run:(NSTimer *)timer
- {
- self.count++;
- CGPoint center = self.aircraftView.center;
- center.y = self.startPoint.y + self.count * (80 - self.startPoint.y) / (FPS * DURATION);
- self.aircraftView.center = center;
- if(self.count >= FPS * DURATION) [timer invalidate];
- }
如果是减速运动每次移动的距离则逐步减小,代码如下所示:
- - (void) run:(NSTimer *)timer
- {
- CGPoint center = self.aircraft.center;
- //当前值=上一次的值+(目标值-上一次值)*渐近因子
- center.y = center.y + (100-center.y)*0.1;
- self.aircraft.center = center;
- if (center.y - 100 <= 1E-6) {
- [timer invalidate];
- }
- }