如何为UIImage或UIImageView添加动画效果?

7
我想要通过动画效果将一个图片的高度从0像素变为480像素,以此来实现图片自上而下的渲染效果。使用UIImageView时,我注意到在Interface Builder中它看起来很正常。但是当它在模拟器中运行时,大小(宽度和高度)总是设置为图像的大小;也就是说,如果我将图像视图的高度设置为原始高度的50%,则仍会完整地呈现图像。
我还尝试使用UIImage来实现这种效果。但是,虽然图像的大小似乎正确,但图像被缩放以反映大小/纵横比。
问题: 如何在不缩放图像的情况下实现此动态调整大小(即对图像大小进行动画处理)?我考虑过使用CGImageCreateWithMask,但我相当确定那会导致巨大的性能问题。
* 更新 *
我想要的效果是: 通过使其高度增长来动画显示一张图片,自上而下(就像在窗户上拉下百叶窗)。这张图片不能被缩放(因为它会失去“百叶窗”外观的视觉效果)。这张图片也必须在另一张图片的上方呈现。所以总共有两张图片。
* 答案 *
对于最上面的imageview,我将内容模式设置为“顶部”(因此它不会缩放)。然后在代码中,我将clipsToBounds设置为True。现在我能够动画显示最上面的imageview高度,从而给我想要的效果。
6个回答

8

使用如下动画块:

imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 0)];
imageView.image = ...;
[imageView setClipsToBounds:YES];
[imageView setContentMode:UIViewContentModeTop];

[self.view addSubview:imageView];
[imageView release];

[UIView animateWithDuration:4.0f
                      delay:1.0f
                    options:UIViewAnimationOptionCurveEaseIn
                 animations:^(void) {
                     imageView.frame = CGRectMake(0, 0, 320, 480);
                 }
                 completion:NULL];

只是好奇,使用动画块是否比使用一般的UIView动画(在其中开始和提交动画)更好? - AlvinfromDiaspar
@AlvinfromDiaspar,我的示例是否有效?我已在本地测试过,它运行得非常好。 - Jacob Relkin
@Jacob Relkin。这很方便,但还有一件事情缺失。我需要另一张图片来代替白色覆盖层。以下是更好的例子/说明:覆盖层图片是背景图片的x光图像。所以我要实现的效果是,x光图像从顶部向下滚动(不缩放等),而背景“纯色”图像最终消失在“x光”图像后面。 - AlvinfromDiaspar
@Jacob Relkin。基本上,我无法对白色覆盖层进行动画处理。相反,我有两个图像,其中一个必须沿高度调整大小,而不以任何方式缩放图像。同样,由于某种原因,当ImageView在模拟器中呈现时,图像会以其完整大小绘制,而不管我通过IB指定的大小如何。 - AlvinfromDiaspar
@Jacob Relkin。目前是的。 - AlvinfromDiaspar
显示剩余3条评论

2

这里有一个建议,假设你有两张图片:A 和 X(X 光图像):

+-------+               +-------+
|       |               |       |
|       |               |       |
|   A   |               |   X   |
|       |               |       |
|       |               |       |
+-------+               +-------+

动态地可以创建一个一像素高的图片(temp),从X部分复制内容,将其放在A的顶部:
+-------+   +-------+   +-------+
|       |   | temp1 | < |       |
|       |   +-------+   |       |
|   A   |               |   X   |
|       |               |       |
|       |               |       |
+-------+               +-------+

在循环中,动态创建/调整临时图像,并从X:复制更多内容。
+-------+   +-------+   +-------+
|       |   | temp2 | < |       |
|       |   |       |   |       |
|   A   |   +-------+   |   X   |
|       |               |       |
|       |               |       |
+-------+               +-------+

+-------+   +-------+   +-------+
|       |   | temp3 | < |       |
|       |   |       |   |       |
|   A   |   |       |   |   X   |
|       |   +-------+   |       |
|       |               |       |
+-------+               +-------+
+-------+   +-------+   +-------+
|       |   | temp4 | < |       |
|       |   |       |   |       |
|   A   |   |       |   |   X   |
|       |   |       |   |       |
|       |   +-------+   |       |
+-------+               +-------+

+-------+   +-------+   +-------+
|       |   | tempX | < |       |
|       |   |       |   |       |
|   A   |   |       |   |   X   |
|       |   |       |   |       |
|       |   |       |   |       |
+-------+   +-------+   +-------+

我曾考虑过这个,但没有去做,因为我知道它会非常低效,而且可能会很慢/卡顿。 - AlvinfromDiaspar

2

2

如原帖所述,这是我偶然发现的答案:

对于最上面的ImageView,我将内容模式设置为顶部(这样它就不会缩放)。然后在代码中,我将clipsToBounds设置为True。现在我可以动画化最上面的ImageView高度,从而给我想要的效果。


0

尝试将您的UIImageView的contentMode属性设置为以下值之一。我认为您需要的是UIViewContentModeScaleAspectFit

typedef enum {
    UIViewContentModeScaleToFill,
    UIViewContentModeScaleAspectFit,      // contents scaled to fit with fixed aspect. remainder is transparent
    UIViewContentModeScaleAspectFill,     // contents scaled to fill with fixed aspect. some portion of content may be clipped.
    UIViewContentModeRedraw,              // redraw on bounds change (calls -setNeedsDisplay)
    UIViewContentModeCenter,              // contents remain same size. positioned adjusted.
    UIViewContentModeTop,
    UIViewContentModeBottom,
    UIViewContentModeLeft,
    UIViewContentModeRight,
    UIViewContentModeTopLeft,
    UIViewContentModeTopRight,
    UIViewContentModeBottomLeft,
    UIViewContentModeBottomRight,
} UIViewContentMode;

如果我使用UIViewContentModeTop,我可以实现我想要的效果。同样,在IB中,这个效果看起来是正确的。但是当我在模拟器中运行时,图像总是显示为图像的实际大小(而不是我在IB中指定的大小)。 - AlvinfromDiaspar
我对你的描述感到困惑。1)你能发布一些屏幕截图吗?2)虽然你在IB中有一组设置,但是你的代码可能在运行时修改/覆盖它们。3)模拟器可能不准确,请尝试在真实的iPhone上测试。 - Di Wu
想象一下在非常慢的连接上呈现网页。基本上你会看到页面从上到下被绘制出来。我想创建这种效果,其中图像是一个320 x 480的图像(UIImage或UIImageView),通过缓慢增加图像的高度从y = 0到y = 480。内容模式定义为顶部(这样图像在调整大小时不会缩放)。 - AlvinfromDiaspar
现在我明白了。你考虑过以下两种方法吗:1)固定图像视图及其图像的位置。2)使用一个带有与背景相同颜色的动画遮罩(可能是另一个图像视图),以产生这样的效果? - Di Wu
当你说“动画遮罩”时,你是否意味着即时创建一个新图像,然后绘制混合结果图像?如果是这样,那么每次更新/周期都会创建一个新图像,这不会非常昂贵(而且很卡顿)吗? - AlvinfromDiaspar

0
你应该看一下iPad上的Flip Clock教程。它使用核心动画,因此具有性能优势。

哎呀。 看起来你访问的页面不存在。 - Anton Tropashko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接