多触摸应用编程与简单动画实现
1. 多触摸应用编程
在开发多触摸应用时,我们可以通过一些简单的操作来实现特定功能,比如移动图像。以下是具体步骤:
1. 按下
Command - R
在 iPhone 模拟器上测试应用程序。
2. 此时可以点击图像视图,然后通过移动手指将图像移动到屏幕上的任意位置。
其工作原理是,当手指点击屏幕时,会检查手指的位置是否在图像视图的范围内:
CGPoint touchPoint = [touch locationInView:[self view]];
if (touchPoint.x > imageView.frame.origin.x &&
touchPoint.x < imageView.frame.origin.x + imageView.frame.size.width &&
touchPoint.y > imageView.frame.origin.y &&
touchPoint.y < imageView.frame.origin.y + imageView.frame.size.height) {
[imageView setCenter:touchPoint];
}
如果手指位置在图像视图范围内,就通过调用
setCenter
属性重新定位图像视图。利用这种技术,还可以轻松编写拼图应用,用户可以在屏幕上拖动拼图的不同部分进行重新排列。
在检测触摸事件方面,需要处理以下四个事件:
-
touchesBegan:withEvent:
-
touchesEnded:withEvent:
-
touchesMoved:withEvent:
-
touchesCancelled:withEvent:
检测点击(单点击、双点击等)可以在
touchesBegan:withEvent:
或
touchesEnded:withEvent:
方法中进行。实现“捏合”手势时,需要比较两个触摸点之间的距离,从而推断是放大还是缩小手势。实现“拖动”手势时,要确保触摸点落在相关视图所占据的区域内。
下面是一个简单的表格总结多触摸应用编程的关键知识点:
| 功能 | 实现方法 |
| ---- | ---- |
| 检测触摸事件 | 处理
touchesBegan:withEvent:
、
touchesEnded:withEvent:
、
touchesMoved:withEvent:
、
touchesCancelled:withEvent:
事件 |
| 检测点击 | 在
touchesBegan:withEvent:
或
touchesEnded:withEvent:
方法中检测 |
| 实现“捏合”手势 | 比较两个触摸点距离推断缩放 |
| 实现“拖动”手势 | 确保触摸点在视图区域内 |
2. 使用 NSTimer 类进行简单动画
NSTimer
类是实现简单动画的一种简便方式。它可以创建定时器对象,以固定的时间间隔调用方法。通过
NSTimer
对象,可以定期更新图像,从而产生动画效果。
以下是使用
NSTimer
类显示弹跳球动画的具体步骤:
1. 使用 Xcode 创建一个新的基于视图的应用程序项目,命名为
Animation
。
2. 将名为
tennisball.jpg
的图像拖放到 Xcode 的资源文件夹中,在出现的添加对话框中,选中“Copy Item into Destination Group’s Folder (If Needed)”复选框,将图像复制到项目中。
3. 双击
AnimationViewController.xib
文件,在 Interface Builder 中进行编辑。
4. 在视图窗口中,拖放一个
ImageView
并将其
Image
属性设置为
tennisball.jpg
。注意要确保
ImageView
的大小适合网球图像,因为后续要在屏幕上移动它,所以不要让它填满整个屏幕。
5. 选择视图(
ImageView
外部),将背景颜色更改为黑色。
6. 从库中添加一个
Label
和一个
Slider
视图到视图窗口,并将
Slider
视图的初始属性设置为
0.01
。
7. 在
AnimationViewController.h
文件中,声明以下出口、动作和字段:
#import <UIKit/UIKit.h>
@interface AnimationViewController : UIViewController {
IBOutlet UIImageView *imageView;
IBOutlet UISlider *slider;
CGPoint position;
NSTimer *timer;
float ballRadius;
}
@property (nonatomic, retain) UIImageView *imageView;
@property (nonatomic, retain) UISlider *slider;
-(IBAction) sliderMoved:(id) sender;
@end
- 返回 Interface Builder,连接出口和动作。
-
在
AnimationViewController.m文件中,添加以下代码:
#import "AnimationViewController.h"
@implementation AnimationViewController
@synthesize imageView;
@synthesize slider;
-(void) onTimer {
imageView.center = CGPointMake(
imageView.center.x + position.x,
imageView.center.y + position.y);
if (imageView.center.x > 320 - ballRadius || imageView.center.x < ballRadius)
position.x = -position.x;
if (imageView.center.y > 460 - ballRadius || imageView.center.y < ballRadius)
position.y = -position.y;
}
- (void)viewDidLoad {
ballRadius = imageView.frame.size.width/2;
[slider setShowValue:YES];
position = 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)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)dealloc {
[timer invalidate];
[imageView release];
[slider release];
[super dealloc];
}
@end
-
按下
Command - R在 iPhone 模拟器上测试应用程序。此时可以看到网球在屏幕上动画显示,通过移动滑块可以改变动画的速度,向右移动滑块会减慢动画速度,向左移动则会加快。
工作原理如下:
- 视图加载时,首先获取网球的半径,即图像宽度的一半:
ballRadius = imageView.frame.size.width/2;
,这个值用于在动画过程中检查网球是否触及屏幕边缘。
- 使用
setShowValue:YES
方法让滑块显示其值。
- 初始化
position
变量,指定图像每次定时器触发时移动的像素数,这里设置为水平移动 12 像素,垂直移动 4 像素。
- 调用
NSTimer
类的
scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
类方法创建一个新的
NSTimer
对象,将定时器触发间隔设置为滑块的值。
- 在
onTimer
方法中,通过设置
ImageView
的
center
属性改变其位置,重新定位后检查图像是否触及屏幕边缘,如果触及则反转
position
变量的值。
- 当移动滑块时,会调用
sliderMoved:
方法,先使当前的
NSTimer
对象无效,然后创建一个新的
NSTimer
对象。
为了使动画更平滑,可以在动画块中设置视图的
center
属性,通过
UIView
类的
beginAnimations:context:
方法开始动画块,
commitAnimations
方法结束动画块:
[UIView beginAnimations:@"my_own_animation" context:nil];
imageView.center = CGPointMake(
imageView.center.x + position.x,
imageView.center.y + position.y);
[UIView commitAnimations];
3. 视图变换
除了使用
NSTimer
类通过不断改变
ImageView
的位置来模拟简单动画外,还可以使用 iPhone SDK 支持的变换技术实现相同效果。iPhone SDK 支持标准的仿射 2D 变换,包括:
- 平移(Translation):使用指定的 x 和 y 轴移动视图的原点。
- 旋转(Rotation):按指定的角度移动视图。
- 缩放(Scaling):按指定的 x 和 y 因子改变视图的比例。
以下是使用这些变换的具体实现:
平移
可以使用视图的
transform
属性进行仿射变换,通过
CGAffineTransformMakeTranslation()
函数返回的
CGAffineTransform
数据结构设置
transform
属性:
//---in the AnimationviewController.h file---
CGPoint position;
CGPoint translation;
//---in the viewDidLoad method---
position = CGPointMake(12.0,4.0);
translation = CGPointMake(0.0,0.0);
-(void) onTimer {
imageView.transform = CGAffineTransformMakeTranslation(
translation.x, translation.y);
translation.x = translation.x + position.x;
translation.y = translation.y + position.y;
if (imageView.center.x + translation.x > 320 - ballRadius ||
imageView.center.x + translation.x < ballRadius)
position.x = -position.x;
if (imageView.center.y + translation.y > 460 - ballRadius ||
imageView.center.y + translation.y < ballRadius)
position.y = -position.y;
}
旋转
在
AnimationViewController.h
文件中添加
angle
变量的声明:
#import <UIKit/UIKit.h>
@interface AnimationViewController : UIViewController {
IBOutlet UIImageView *imageView;
IBOutlet UISlider *slider;
CGPoint position;
NSTimer *timer;
float ballRadius;
float angle;
}
@property (nonatomic, retain) UIImageView *imageView;
@property (nonatomic, retain) UISlider *slider;
-(IBAction) sliderMoved:(id) sender;
@end
在
AnimationViewController.m
文件中添加旋转相关代码:
-(void) onTimer {
//---rotation---
imageView.transform = CGAffineTransformMakeRotation(angle);
angle += 0.02;
if (angle>6.2857) angle = 0;
imageView.center = CGPointMake(
imageView.center.x + position.x,
imageView.center.y + position.y);
if (imageView.center.x > 320 - ballRadius || imageView.center.x < ballRadius)
position.x = -position.x;
if (imageView.center.y > 460 - ballRadius || imageView.center.y < ballRadius)
position.y = -position.y;
}
- (void)viewDidLoad {
//---set the angle to 0---
angle = 0;
ballRadius = imageView.frame.size.width/2;
[slider setShowValue:YES];
position = CGPointMake(12.0,4.0);
timer = [NSTimer scheduledTimerWithTimeInterval:slider.value
target:self
selector:@selector(onTimer)
userInfo:nil
repeats:YES];
[super viewDidLoad];
}
按下
Command - R
测试应用程序,网球在弹跳的同时会旋转。其工作原理是,通过
CGAffineTransformMakeRotation()
函数返回的
CGAffineTransform
数据结构设置
transform
属性,每次旋转后将角度增加 0.02,当角度超过 6.2857(即 2π 弧度)时,将角度重置为 0。
缩放
使用
CGAffineTransformMakeScale()
函数返回的
CGAffineTransform
数据结构设置视图的
transform
属性进行缩放:
imageView.transform = CGAffineTransformMakeScale(angle, angle);
如果在之前的示例中添加此语句,网球在屏幕上弹跳时会变大,然后恢复到原始大小并再次变大。
4. 动画系列图像
除了显示静态图像,
ImageView
还可以显示一系列图像并在它们之间交替。以下是具体步骤:
1. 使用 Xcode 创建一个新的基于视图的应用程序项目,命名为
Animations2
。
2. 将一系列图像拖放到 Xcode 的资源文件夹中,在添加对话框中选中“Copy Item into Destination Group’s Folder (If Needed)”复选框,将每个图像的副本复制到项目中。
3. 在
Animations2ViewController.m
文件中,添加以下代码:
- (void)viewDidLoad {
NSArray *images = [NSArray arrayWithObjects:
[UIImage imageNamed:@"MacSE.jpeg"],
[UIImage imageNamed:@"imac.jpeg"],
[UIImage imageNamed:@"MacPlus.jpg"],
[UIImage imageNamed:@"imac_old.jpeg"],
[UIImage imageNamed:@"Mac8100.jpeg"],
nil];
CGRect frame = CGRectMake(0,0,320,460);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.animationImages = images;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.animationDuration = 3; //---seconds to complete one set of animation---
imageView.animationRepeatCount = 0; //---continuous---
[imageView startAnimating];
[self.view addSubview:imageView];
[imageView release];
[super viewDidLoad];
}
-
按下
Command - R在 iPhone 模拟器上测试,图像将在ImageView中依次显示。
工作原理是,首先创建一个
NSArray
对象并使用几个
UIImage
对象初始化它,然后实例化一个
UIImageView
对象,将其
animationImages
属性设置为
images
对象,设置显示模式,通过
animationDuration
属性控制图像显示速度,
animationRepeatCount
属性指定动画重复次数,最后调用
startAnimating
方法开始动画,并将
ImageView
添加到视图中。
总结
通过上述内容,我们了解了
NSTimer
类的实用性,它可以帮助我们执行一些简单的动画。还学习了 iPhone SDK 支持的各种仿射变换,以及
ImageView
以固定时间间隔动画显示一系列图像的能力。
相关练习
-
说出 iPhone SDK 支持的三种仿射变换。
- 平移(Translation)
- 旋转(Rotation)
- 缩放(Scaling)
-
如何暂停
NSTimer对象然后使其继续?-
暂停:使用
[timer invalidate];使NSTimer对象无效。 -
继续:重新创建一个新的
NSTimer对象。
-
暂停:使用
-
将代码块用
UIView类的beginAnimations和commitAnimations方法包围有什么作用?- 作用是将代码块中的视觉变化封装在一个动画块中,使动画更加平滑。
关键知识点总结
| 主题 | 关键概念 |
|---|---|
使用
NSTimer
对象创建定时器
|
Timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
|
停止
NSTimer
对象
|
[timer invalidate];
|
| 动画视觉变化 |
[UIView beginAnimations:@"some_text" context:nil]; //---code to effect visual change--- [UIView commitAnimations];
|
| 执行仿射变换 |
使用视图的
transform
属性,平移使用
CGAffineTransformMakeTranslation()
函数,旋转使用
CGAffineTransformMakeRotation()
函数,缩放使用
CGAffineTransformMakeScale()
函数
|
使用
ImageView
动画系列图像
|
设置
animationImages
属性为包含
UIImage
对象的数组,设置
animationDuration
属性,设置
animationRepeatCount
属性,调用
startAnimating
方法
|
流程图
graph TD;
A[开始] --> B[创建项目];
B --> C[添加资源];
C --> D[编辑界面];
D --> E[编写代码];
E --> F[测试应用];
F --> G{是否满足需求};
G -- 是 --> H[结束];
G -- 否 --> E;
通过以上内容,我们可以全面掌握多触摸应用编程和简单动画实现的相关知识和技能,为开发更丰富的应用程序打下基础。在实际开发中,可以根据具体需求灵活运用这些技术,创造出更具吸引力和交互性的应用。
多触摸应用编程与简单动画实现
5. 多触摸应用编程与动画技术的综合应用思路
在实际开发中,多触摸应用编程和简单动画技术并非孤立存在,而是可以相互结合,创造出更具交互性和趣味性的应用。例如,在一个拼图游戏中,可以结合多触摸的拖动功能和动画效果,让用户在拖动拼图块时,拼图块有平滑的移动动画,并且在拼合成功时,给予一个简单的缩放或旋转动画作为反馈。
以下是一个简单的综合应用思路示例:
1.
创建拼图游戏界面
:使用多触摸应用编程的知识,允许用户通过触摸拖动拼图块到合适的位置。
2.
添加动画效果
:
- 在拖动拼图块时,使用
UIView
的动画块让拼图块的移动更加平滑。
- 当拼图块拼合成功时,使用仿射变换的旋转或缩放效果,让拼图块有一个短暂的动画反馈。
3.
优化用户体验
:使用
NSTimer
类可以实现一些定时的提示功能,比如在用户长时间未完成拼图时,弹出提示信息。
6. 代码优化与性能提升
在开发过程中,代码优化和性能提升是非常重要的。以下是一些针对上述技术的优化建议:
-
内存管理
:在使用
NSTimer
对象时,要确保在不需要时及时调用
[timer invalidate];
方法,避免内存泄漏。同时,对于
UIImageView
和其他视图对象,也要在合适的时候进行释放。
-
动画性能
:在使用
beginAnimations
和
commitAnimations
方法时,尽量减少动画块内的复杂计算,以免影响动画的流畅性。对于一些复杂的动画,可以考虑使用更高级的动画框架。
-
代码结构
:将不同的功能模块封装成独立的方法,提高代码的可读性和可维护性。例如,将
NSTimer
的创建和管理封装成一个单独的方法。
7. 常见问题及解决方案
在开发过程中,可能会遇到一些常见问题,以下是一些问题及对应的解决方案:
| 问题 | 解决方案 |
| ---- | ---- |
|
NSTimer
不触发 | 检查
scheduledTimerWithTimeInterval
方法的参数是否正确,确保
repeats
参数设置为
YES
,并且
target
和
selector
方法正确。 |
| 动画不流畅 | 检查动画块内的代码是否有复杂计算,尝试减少不必要的操作。同时,可以调整
animationDuration
属性,优化动画速度。 |
| 触摸事件不响应 | 检查视图的
userInteractionEnabled
属性是否设置为
YES
,确保视图可以接收触摸事件。 |
8. 未来发展趋势
随着移动设备性能的不断提升和用户对应用交互性要求的提高,多触摸应用编程和简单动画技术也将不断发展。以下是一些可能的发展趋势:
-
更复杂的手势识别
:除了现有的单指触摸和双指捏合手势,未来可能会支持更多复杂的手势,如三指或四指手势,为用户提供更丰富的交互方式。
-
3D 动画效果
:随着 3D 技术的发展,简单的 2D 动画可能会逐渐向 3D 动画过渡,为用户带来更逼真的视觉体验。
-
增强现实(AR)和虚拟现实(VR)结合
:多触摸和动画技术可能会与 AR 和 VR 技术相结合,创造出更加沉浸式的应用体验。
总结
通过对多触摸应用编程、使用
NSTimer
类进行简单动画、视图变换以及动画系列图像等技术的学习,我们可以开发出更具交互性和趣味性的应用。在实际开发中,要注意代码优化和性能提升,解决常见问题,并关注未来的发展趋势,不断提升自己的开发能力。
流程图
graph TD;
A[开发应用] --> B[多触摸编程];
A --> C[简单动画];
B --> D[触摸事件处理];
B --> E[手势识别];
C --> F[NSTimer 应用];
C --> G[仿射变换];
C --> H[动画系列图像];
D --> I[拖动功能];
E --> J[捏合手势];
F --> K[定时动画];
G --> L[平移];
G --> M[旋转];
G --> N[缩放];
H --> O[图像交替显示];
I --> P[拼图游戏];
J --> Q[缩放效果];
K --> R[提示功能];
L --> S[视图移动];
M --> T[视图旋转];
N --> U[视图缩放];
O --> V[动画展示];
P --> W[综合应用];
Q --> W;
R --> W;
S --> W;
T --> W;
U --> W;
V --> W;
通过以上内容,我们对多触摸应用编程和简单动画技术有了更深入的了解,并且掌握了如何将这些技术应用到实际开发中,以及如何进行优化和应对常见问题。希望这些知识能够帮助你开发出更加优秀的移动应用。
超级会员免费看
758

被折叠的 条评论
为什么被折叠?



