动画使用顺序的图像阵列

Yad*_*esh 18 animation cocoa-touch objective-c ios

我有一系列图像,我想通过在序列中依次播放这些图像来制作动画.我想多次重复整个循环.我正在为iPad开发游戏.向我建议一种使用Cocoa框架在Objective-C中实现此功能的方法.

Gyp*_*psa 50

NSArray *animationArray = [NSArray arrayWithObjects:
                          [UIImage imageNamed:@"images.jpg"],
                          [UIImage imageNamed:@"images1.jpg"],
                          [UIImage imageNamed:@"images5.jpg"],
                          [UIImage imageNamed:@"index3.jpg"],
                          nil];
UIImageView *animationView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0,320, 460)];
animationView.backgroundColor      = [UIColor purpleColor];
animationView.animationImages      = animationArray;
animationView.animationDuration    = 1.5;
animationView.animationRepeatCount = 0;
[animationView startAnimating]; 
[self.view addSubview:animationView];       
[animationView release];
Run Code Online (Sandbox Code Playgroud)

在array.repeat中添加您自己的图像.计数0表示无限循环.您也可以给出自己的数字.


Gab*_*ana 18

至少有3种方法可以通过a来动画一组图像UIImageView.我正在添加3个链接来下载3种可能性的示例代码.

第一个是每个人都知道的.其他人鲜为人知.

- UIImageView.animationImages
示例链接

这个的问题是没有委托告诉我们动画完成的时刻.因此,如果我们想要在动画之后显示某些内容,我们就会遇到问题.

以同样的方式,不可能自动保留动画中的最后一个图像UIImageView.如果我们将这两个问题结合起来,如果我们想要在屏幕上保留最后一帧,我们可以在动画结尾处留下间隙.

self.imageView.animationImages = self.imagesArray; // the array with the images
self.imageView.animationDuration = kAnimationDuration; // static const with your value
self.imageView.animationRepeatCount = 1;
[self.imageView startAnimating];
Run Code Online (Sandbox Code Playgroud)

- CAKeyframeAnimation
示例链接

这种动画制作方式CAAnimation.它有一个易于使用的委托,我们可以知道动画何时完成.

这可能是动画图像数组的最佳方式.

- (void)animateImages
{
    CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
    keyframeAnimation.values = self.imagesArray;

    keyframeAnimation.repeatCount = 1.0f;
    keyframeAnimation.duration = kAnimationDuration; // static const with your value

    keyframeAnimation.delegate = self;

    //    keyframeAnimation.removedOnCompletion = YES;
    keyframeAnimation.removedOnCompletion = NO;
    keyframeAnimation.fillMode = kCAFillModeForwards;

    CALayer *layer = self.animationImageView.layer;

    [layer addAnimation:keyframeAnimation
                 forKey:@"girlAnimation"];
}
Run Code Online (Sandbox Code Playgroud)

代表:

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (flag)
    {
        // your code
    }
}
Run Code Online (Sandbox Code Playgroud)

- CADisplayLink
示例链接

A CADisplayLink object is a timer object that allows your application to synchronize its drawing to the refresh rate of the display.

这种方式非常有趣,并且可以操作我们在屏幕中显示的内容.

DisplayLink getter:

- (CADisplayLink *)displayLink
{
    if (!_displayLink)
    {
        _displayLink = [CADisplayLink displayLinkWithTarget:self
                                                   selector:@selector(linkProgress)];
    }

    return _displayLink;
}
Run Code Online (Sandbox Code Playgroud)

方法:

- (void)animateImages
{
    self.displayLink.frameInterval = 5;
    self.frameNumber = 0;
    [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop]
                           forMode:NSRunLoopCommonModes];
}

- (void)linkProgress
{
    if (self.frameNumber > 16)
    {
        [self.displayLink invalidate];
        self.displayLink = nil;
        self.animationImageView.image = [UIImage imageNamed:@"lastImageName"];
        self.imagesArray = nil;
        return;
    }

    self.animationImageView.image = self.imagesArray[self.frameNumber++];
    self.frameNumber++;
}
Run Code Online (Sandbox Code Playgroud)

一般问题:

即使我们有这3种可能性,如果你的动画有很多大图像,请考虑使用视频.内存的使用会减少很多.

您将要面对的一般问题是在分配图像的那一刻.

如果您使用[UIImage imageNamed:@"imageName"],您将遇到问题.

来自Apple:

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method locates and loads the image data from disk or asset catelog, and then returns the resulting object. You can not assume that this method is thread safe.

因此,imageNamed:将图像存储在私有缓存中.
- 第一个问题是您无法控制缓存大小.
- 第二个问题是缓存没有得到及时清理,如果你要分配大量图像imageNamed:,你的应用程序可能会崩溃.

解:

直接从Bundle以下位置分配图像:

NSString *imageName = [NSString stringWithFormat:@"imageName.png"];
NSString *path = [[NSBundle mainBundle] pathForResource:imageName

// Allocating images with imageWithContentsOfFile makes images to do not cache.
UIImage *image = [UIImage imageWithContentsOfFile:path];
Run Code Online (Sandbox Code Playgroud)

小问题:

中的图像Images.xcassets从未分配过.因此,将图像移到外面Images.xcassets以直接从Bundle分配.


zou*_*oul 11

看到的animationImages财产UIImageView.很难说它是否符合您的需求,因为您没有向我们提供详细信息,但这是一个良好的开端.