读书频道 > 网站 > 网页设计 > iOS 5编程入门经典(第3版)——开发iPhone与iPad应用
13.1 使用NSTimer类
12-11-08    奋斗的小年轻
收藏    我要投稿   
本书面向iPhone和iPad开发初学者,涵盖了iOS开发的各个主题。本书的编写方式是渐进式的,这样读者就不会由于细节过多而疲于奔命。我认为最好的学习方式就是去实践,因此全书大量的试一试首先会介绍如何构建某个应...立即去当当网订购

学习动画最简单的一种方式就是使用NSTimer 类。NSTimer 类用于创建定时器对象,从而每隔一段时间就调用方法。借助于NSTimer 对象,可以定期更新图像,这就会造成一种感觉:图像是动态的。

下面的“试一试”将介绍如何使用NSTimer 类在屏幕上显示一个网球。当网球触碰到屏幕边缘时,它会弹到相反的方向。另外还将介绍如何控制网球滚动的频率。在开始之前,需要先下载本章所有“试一试”练习的代码文件。

 试一试 创建连续滚动的网球

代码文件Animation.zip可从Wrox.com下载

代码文件Animation.zip可从Wrox.com下载

(1) 使用Xcode 创建一个新的Single View Application(iPhone) 项目,命名为Animation 。使用项目名称作为Class Prefix,并取消选中Use Automatic Reference Counting选项。

(2) 将名为tennisball.jpg 的一幅图像拖放到Xcode 的Supporting Files文件夹下。当弹出Add 对话框时,可以根据需要选中Copy Item into the Destination Group’s Folder 复选框,以便将图像复制到该项目中,如图13-1 所示。


 

(3) 选择AnimationViewController.xib文件,在Interface Builder 中编辑它。

(4) 将Image View 拖放到View 窗口中并将其Image属性设置为tennisball.jpg ,如图13-2 所示。

确保Image View的尺寸适合网球图像。稍后将在屏幕上移动Image View,因此请不要将Image View填满整个屏幕。


 

(5) 选择View窗口(在Image View之外)并将背景色改为黑色,如图13-3所示。


 

(6) 从Library 中将一个Label 视图与一个Slider 视图添加到View 窗口中,如图13-4 左下角所示。将Slider视图的InitialCurrent 属性设置为0.01 。


 

(7) 在AnimationViewController.h 文件中声明如下插座变量、字段与动作(粗体显示):
#import <UIKit/UIKit.h>

@interface AnimationViewController : UIViewController
{
    IBOutlet UIImageView *imageView;
    IBOutlet UISlider *slider;

    CGPoint delta;
    NSTimer *timer;
    float ballRadius;
}

@property (nonatomic, retain) UIImageView *imageView;
@property (nonatomic, retain) UISlider *slider;

-(IBAction) sliderMoved:(id) sender;

@end

(8) 回到Interface Builder ,按照如下方法连接插座变量与动作(得到的连接如图13-5 所示):

● 按住Control 键并把File’’s Owner 项拖放到Image View 上,选择imageView 。

● 按住Control 键并把File’’s Owner 项拖放到Slider 视图上,选择slider 。

● 按住Control 键并把Slider 视图拖放到File’’s Owner 项上,选择“sliderMoved:”。


 

(9) 在AnimationViewController.m文件中添加如下粗体语句:
 #import "“AnimationViewController.h"”

@implementation AnimationViewController

@synthesize imageView;
@synthesize slider;

-(void) onTimer {   
    imageView.center = CGPointMake(imageView.center.x + delta.x,
                                         imageView.center.y + delta.y);

    if (imageView.center.x > self.view.bounds.size.width - ballRadius ||
        imageView.center.x < ballRadius)
        delta.x = -delta.x;

    if (imageView.center.y > self.view.bounds.size.height - ballRadius ||
        imageView.center.y < ballRadius)
        delta.y = -delta.y;
}

- (void) viewDidLoad {
    ballRadius = imageView.bounds.size.width / 2;
    [slider setShowValue:YES];
    delta = CGPointMake(12.0,4.0);
    timer = [NSTimer scheduledTimerWithTimeInterval:slider.value
                                                     target:self
                                                  selector:@selector(onTimer)
                                                  userInfo:nil
                                                   repeats:YES];
    [super viewDidLoad];
}

-(IBAction) sliderMoved:(id) sender {   
    [timer invalidate];   
    timer = [NSTimer scheduledTimerWithTimeInterval:slider.value
                                             target:self
                                           selector:@selector(onTimer)
                                                   userInfo:nil
                                                   repeats:YES];
}

- (void)dealloc {
    [timer invalidate];
    [imageView release];
    [slider release];
    [super dealloc];
}

(10) 按Command+R组合键,在iPhone Simulator 中测试应用程序。现在应该会看到网球在屏幕上滚动,如图13-6所示。可以通过移动滑块来改变网球滚动的速度。将滑块右移会减慢滚动的速度,左移则会加快滚动的速度。


 

示例说明

当视图加载后,所做的第一件事就是获得网球的半径,在本例中半径是图像宽度的一半:

    ballRadius = imageView.bounds.size.width / 2;

这个值用于在网球滚动过程中检查网球是否触碰到屏幕边缘。

接下来使用“setShowValue: :”方法来显示滑块的值:
    [slider setShowValue:YES];

注意:“setShowValue:”方法是文档中未公开的方法,因此编译器会发出一个警告。需要注意的是,如果应用程序使用未在文档中公开的方法,那么在提交时Apple可能会拒绝接受该应用程序。一般来说,只能在进行调试时使用未在文档中公开的方法。

使用如下代码初始化delta 变量:

    delta = CGPointMake(12.0,4.0);   

delta 变量用于指定每次定时器触发时图像要移动的距离。上述代码说明图像每次会沿水平方向移动12 个像素、沿垂直方向移动4个像素。

接下来调用NSTimer 类的“scheduledTimerWithTimeInterval:target:selector:userInfo: repeats:”方法来创建NSTimer 类的一个新实例:
    timer = [NSTimer scheduledTimerWithTimeInterval:slider.value
                                                     target:self
                                                  selector:
                                               @selector(onTimer)
                                                   userInfo:nil
                                                   repeats:YES];

“scheduledTimerWithTimeInterval:”参数指定定时器两次触发所间隔的秒数,这里将它设置为Slider 视图的值,范围是0.0~1.0 。例如,如果滑块的值是0.5 ,那么timer 对象就每隔半秒触发一次。

“selector:”参数指定定时器触发时所调用的方法,“repeats:”参数表示timer 对象是否会重复调度自身。在本例中,当定时器触发时,它会调用后面定义的onTimer 方法。

在onTimer 方法中,通过将Image View 视图的center 属性设置为新值来改变该视图的位置。重新定位后,检查图像是否触碰到屏幕的边缘;如果触碰到,delta 变量的值就是负数:
-(void) onTimer {
    imageView.center = CGPointMake(imageView.center.x + delta.x,
                                   imageView.center.y + delta.y);
    if (imageView.center.x >
           self.view.bounds.size.width - ballRadius ||
        imageView.center.x < ballRadius)
        delta.x = -delta.x;

    if (imageView.center.y >
           self.view.bounds.size.height - ballRadius ||
        imageView.center.y < ballRadius)
        delta.y = -delta.y;
}

当移动滑块时会调用“sliderMoved:”方法。在该方法中,首先会使timer 对象无效,然后创建NSTimer 类的另一个实例:
-(IBAction) sliderMoved:(id) sender {
    [timer invalidate];
    timer = [NSTimer scheduledTimerWithTimeInterval:slider.value
                                                     target:self
                                                   selector:
                                              @selector(onTimer)
                                           userInfo:nil
                                                     repeats:YES];
}

移动滑块可以改变图像滚动的频率。

注意:启动NSTimer对象后,就不能改变其触发时间间隔。改变时间间隔的唯一办法就是使当前的定时器对象无效,然后创建一个新的NSTimer对象。

创建连续变化的视觉效果

你可能已经注意到了,在向右移动滑块时,动画速度会变慢,网球的滚动也变得有些不连贯。要想让动画变得更加流畅,可以使用“动画代码块”来创建连续变化的视觉效果。

UIView 类的“banimateWithDuration:delay:options:animations:completion:”方法就是这样一个动画代码块的:你可能已经注意到了,在向右移动滑块时,动画速度会变慢,网球的滚动也变得有些不连贯。要想让动画变得更加流畅,可以使用“动画代码块”来创建连续变化的视觉效果。UIView类的“animateWithDuration:delay:options:animations:completion:”方法就是这样一个动画代码块的方法:
[UIView animateWithDuration :slider.value 
                          delay :0.0f
                        options :UIViewAnimationOptionAllowUserInteraction |
                             UIViewAnimationOptionCurveLinear
                     animations :^{
                      imageView.center =
                        CGPointMake(imageView.center.x + delta.x,
                                                     imageView.center.y + delta.y);                        
                     }
                     completion:nil];

前面的代码使用UIViewAnimationOptionCurveLinear(匀速)和UIViewAnimationOption- AllowUserInteraction(在以动画方式显示视图的过程中允许用户与视图交互)动画选项立即执行指定的动画。这么做的结果是得到更加流畅的动画。

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1.3 功能
下一篇:1.5 小结
相关文章
图文推荐
JavaScript网页动画设
1.9 响应式
1.8 登陆页式
1.7 主题式
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站