【问题标题】:Animating a UIImage or UIImageView?为 UIImage 或 UIImageView 设置动画?
【发布时间】:2011-06-13 22:49:21
【问题描述】:

我正在尝试为图像的高度设置动画(从 0 像素高度到 480 像素)以创建自上而下渲染的图像效果。

使用 UIImageView 我注意到它在 Interface Builder 中看起来是正确的。但是当它在模拟器中运行时,大小(宽度和高度)总是设置为图像的大小;这意味着,如果我将图像视图的高度设置为原始高度的 50%,图像仍会以全高呈现。

我也试过用 UIImage 来做这个效果。然而,虽然图像的大小看起来是正确的,但图像会被缩放以反映大小/纵横比。

问题: 如何在不缩放图像的同时实现这种动态大小(即图像大小的动画)?我考虑过使用 CGImageCreateWithMask,但我很确定这会产生巨大的性能问题。

* 更新 *

我正在寻找的效果是这样的: 通过使图像的高度从上到下(就像一组百叶窗被拉到窗户上)来为图像设置动画。此图像无法缩放(因为它会失去看起来像“盲人”的视觉效果)。此图像还必须在另一个图像之上渲染。所以总共有 2 张图片。

* 答案 *

对于最顶部的图像视图,我将内容模式设置为顶部(因此它不会缩放)。然后在代码中,我将 clipsToBounds 设置为 True。现在我可以为最顶部的 imageview 高度设置动画,从而给我想要的效果。

【问题讨论】:

    标签: iphone ios uiimageview


    【解决方案1】:

    像这样使用动画块:

    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 从 iOS 4 开始,它们现在是执行动画的推荐方式。
    • @AlvinfromDiaspar 我的例子有效吗?我在本地测试过,效果很好。
    • @AlvinfromDiaspar 立即尝试 - 应该完全按照您的喜好工作。
    • @Jacob Relkin。这非常漂亮,但是缺少一件事。而不是白色覆盖,我需要覆盖是另一个图像。这是一个更好的示例/解释:叠加图像是背景图像的 X 射线图像。所以我正在寻找的效果是 X 射线图像从顶部向下滚动(没有缩放......等),而背景“实心”图像最终消失在“X 射线”图像后面。
    【解决方案2】:

    您应该查看Flip Clock 的 iPad 教程。它带有核心动画,因此具有性能奖励。

    【讨论】:

    • 呃哦。看起来您访问了一个不存在的页面。
    【解决方案3】:

    正如原帖中提到的,这是我似乎偶然发现的答案:

    对于最顶部的图像视图,我将内容模式设置为顶部(因此它不会缩放)。然后在代码中,我将 clipsToBounds 设置为 True。现在我可以为最顶部的 imageview 高度设置动画,从而得到我正在寻找的效果。

    【讨论】:

      【解决方案4】:

      只是一个建议,假设您有两个图像:A 和 X(X 射线图像):

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

      您可以动态创建一个像素高的图像(temp),从 X 部分复制内容,将其放在 A 之上:

      +-------+   +-------+   +-------+
      |       |   | temp1 | < |       |
      |       |   +-------+   |       |
      |   A   |               |   X   |
      |       |               |       |
      |       |               |       |
      +-------+               +-------+
      

      在循环中,动态创建/调整临时图像大小,并从 X 复制更多内容:

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

      【讨论】:

      • 我想到了这个,但没有这样做,因为我知道它会非常低效,更不用说可能非常慢/断断续续。
      【解决方案5】:

      尝试将 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 中指定的大小)。
      • 我对你的描述感到困惑。 1)你能发布一些屏幕截图吗? 2) 尽管您在 IB 中有一组设置,但您的代码可能在运行时修改/覆盖了它们。 3) 模拟器可能不准确,请尝试在真机上测试。
      • 想象一个网页正在一个非常慢的连接上呈现。您基本上可以看到从上到下绘制的页面。本质上,我想通过将图像的高度从 y=0 缓慢增加到 y=480 来创建这种效果,其中图像是 320x480 图像(UIImage 或 UIImageView)。内容模式定义为顶部(这样在调整图像边界大小时图像不会缩放)。
      • 现在我明白了。您是否考虑过:1)固定图像视图及其图像的位置。 2)使用与背景颜色相同的动画蒙版(可能是另一个图像视图)来制作这样的效果?
      • 当您说“动画蒙版”时,您是指即时创建新图像然后绘制混合结果图像吗?如果是这样,这会不会非常昂贵(并且不稳定),因为在每个更新/周期都会创建一个新图像?
      【解决方案6】:

      您可能想查看动画块。它们在这里记录得非常详尽:

      http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html

      那里的所有代码都是相关的,因为 UIImageView 是 UIView 的子类。

      愉快的编码。

      【讨论】:

        猜你喜欢
        • 2016-02-22
        • 2012-09-23
        • 2017-12-10
        • 1970-01-01
        • 1970-01-01
        • 2012-01-22
        • 2012-11-11
        • 2013-11-13
        • 1970-01-01
        相关资源
        最近更新 更多