UIImageView动画在startAnimating发出几秒后启动

1 iphone animation uiimageview

好吧,我有以下非常简单的动画,由PNG格式的25帧组成.每帧为320×360,大小约为170Kb.这是我使用的代码

.H:

IBOutlet UIImageView *Animation_Normal_View;
Run Code Online (Sandbox Code Playgroud)

在Interface Builder中,我有一个UIImageView,其引用插座指向此.我的所有图像都命名normal_000_crop.png,normal_001_crop.png,normal_002_crop.png,...

.M:

Animation_Normal = [[NSMutableArray alloc] initWithCapacity:25];
for (int i = 0; i < 25; i++)
{
  [Animation_Normal addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"normal_%03d_crop.png", i] ofType:nil]]];
}

Animation_Normal_View.animationImages = Animation_Normal;
Animation_Normal_View.animationDuration = 1; // seconds
Animation_Normal_View.animationRepeatCount = 0; // 0 = loops forever
[Animation_Normal release];


[self.view addSubview:Animation_Normal_View];
[Animation_Normal_View startAnimating];
Run Code Online (Sandbox Code Playgroud)

在模拟器上,所有东西都会像startAnimating一样发出良好的视觉动画.

但在iPhone 3G的运行iOS 4.0.2 startAnimating发出后的视觉动画开始了良好的2〜3秒.

我已经尝试了我可以在博客或论坛中找到的每一种技术都应该解决这个问题无济于事.

即使它是基于PNG的动画的完全不同的方式,任何提示都会受到赞赏.

谢谢.

Kev*_*rry 5

这是一个很好的问题,我将在这里提出一些想法.

首先,您要加载一系列总大小约为4MB的图形.这可能需要一些时间,特别是在较慢(较旧)的设备上.

.h文件的@interface块中,您可能需要声明两个属性,例如:

IBOutlet UIImageView *animationViewNormal;
NSMutableArray *animationViewNormalImages;
Run Code Online (Sandbox Code Playgroud)

第一个是您已经拥有的UIImageView(刚刚重命名为最佳实践),第二个是用于保存图像视图的图像堆栈的可变数组.让我说,如果"正常"意味着国家.为了澄清,您是否为不同的状态加载了其他图像集?

@interface的.m文件中,创建以下方法:

- (void)loadAnimationImages;
Run Code Online (Sandbox Code Playgroud)

这将提供将图像堆栈引导到标头中定义的可变数组的功能.

@implementation中的同一个.m文件中,您需要以下内容:

- (void)loadAnimationImages {
  for (NSUInteger i = 0; i < 23; i++) {
    NSString *imageName = [NSString stringWithFormat:@"normalCrop%03u", i];
    UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:@"png"]];
    if (image) {
      [animationViewNormalImages addObject:image];
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我将PNG文件从normal_%03u_crop重命名为normalCrop%03u,因为最佳做法是将索引标签放在文件名的末尾(大多数应用程序也会以这种方式输出内容).循环加载图像,检查它是否是图像,然后将图像添加到可变数组中的"图像堆栈".

init()中,您需要以下内容:

- (id)init {
  ...
  animationViewNormalImages = [[NSMutableArray alloc] init];
  ...
}
Run Code Online (Sandbox Code Playgroud)

这会分配(animationViewNormalImages)可变数组来保存图像视图的图像堆栈.

我们现在转到viewDidLoad()的代码:

- (void)viewDidLoad {
  [super viewDidLoad];
  ...
  [self loadAnimationImages];
  [animationViewNormal setAnimationImages:animationViewNormalImages];
  [animationViewNormal setAnimationDuration:1.1f];
  [animationViewNormal setAnimationRepeatCount:0];  //  0=infinite loop
  ...
}
Run Code Online (Sandbox Code Playgroud)

我们将图像堆栈加载到可变数组中,然后使用图像堆栈,持续时间和重复计数设置imageView的属性.

接下来在viewDidAppear()中我们启动图像视图动画:

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  ...
  [animationViewNormal startAnimating];
  ...
}
Run Code Online (Sandbox Code Playgroud)

一旦imageView动画为无限循环,我们需要在viewWillDisappear()中离开视图时进行处理:

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  ...
  [animationViewNormal stopAnimating];
  ...
}
Run Code Online (Sandbox Code Playgroud)

最后(这应该是我们添加.m文件的第二件事)我们在dealloc()中的可变数组中进行清理:

- (void)dealloc {
  ...
  [animationViewNormalImages release];
  [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

这就是我们处理它并为我们工作的方式,但话说回来,我们通常不会将4MB图像加载到内存中来制作动画.

构建应用程序时压缩.PNG文件,我不确定在加载资源包的图像时是否动态解压缩.这是构建属性构建设置(COMPRESS_PNG_FILES)中的布尔值.

对于性能,您可能需要考虑以下事项:

  • 标记不透明视图:合成内容不透明的视图比合成部分透明的视图要少得多.要使视图不透明,视图的内容不得包含任何透明度,并且视图的opaque属性必须
    设置为YES.
  • 从不透明PNG文件中删除Alpha通道:如果PNG图像的每个像素都是不透明的,则删除Alpha通道可以避免混合包含该图像的图层.这大大简化了图像的合成,并提高了绘图性能.

此外,您可能会发现使用所有24帧(偏移单个帧的宽度)制作一个大图像然后加载一次会更好.然后使用Core Graphics和CGContextClipToRect,然后只是偏移图像上下文.这意味着更多代码,但可能比使用标准堆栈方法更快.

最后,您可能需要考虑将.PNG文件转换为.PVR(PVRTC)文件.可以在此处找到更多信息:Apple Tech QA,Apple Docs示例代码.

我希望这会有所帮助,如果确实如此,请将其投票.

最好的,Kevin Able Pear软件