如何动画附加到UIImageView的CALayer?

时间:2012-11-12 23:19:43

标签: objective-c ios uiview uiimageview

我正在使用Bartosz提出的code来为UIImageView添加一个掩码。它工作正常。

#import <QuartzCore/QuartzCore.h>

CALayer *mask = [CALayer layer];
mask.contents = (id)[[UIImage imageNamed:@"mask.png"] CGImage];
mask.frame = CGRectMake(0, 0, 320.0, 100.0);
yourImageView.layer.mask = mask;
yourImageView.layer.masksToBounds = YES;

此外,我想为蒙版设置动画,例如将蒙版滑动到右侧,以便在动画结束时,蒙版不再应用于UIImageView。

在我的特定情况下,掩码使用完全透明的图像,因此UIImageView在初始状态下不可见(工作正常),但预计在动画结束时也是如此。但是,如果需要对蒙版进行动画处理,这个想法可以重复用于任何其他用例。

想法是操纵掩模框架的x原点部分。所以,我提出了这个代码:

[UIView animateWithDuration: 0.2
                      delay: 0
                    options: UIViewAnimationCurveEaseInOut
                 animations:^{
                         CGRect maskFrame = yourImageView.layer.mask.frame;
                         maskFrame.origin.x = 320.0;
                         yourImageView.layer.mask.frame = maskFrame;
                     }
                 completion:^(BOOL finished){}];

不幸的是,掩码在任何时候都应用于整个UIImageView,它不会向右滑动。

更新1:

这是我实际使用的设置视图和掩码的代码:它是一个UITableViewCell。

APPCell.m(APPCell.h“扩展”UITableViewCell)

#import "APPCell.h"
#import <QuartzCore/QuartzCore.h>

@interface APPCell()
@property (strong, nonatomic) UIImageView *menu;
@property (strong, nonatomic) CALayer *menuMask;
...
@end

@implementation APPCell
...

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self.menu = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320.0, 88.0)];
[self.menu setBackgroundColor:[UIColor clearColor]];
[self.menu setImage:[UIImage imageNamed:@"cell_back"]];
[self addSubview:self.menu];

self.menuMask = [CALayer layer];
self.menuMask.contents = (id)[[UIImage imageNamed:@"cell_mask"] CGImage];
self.menuMask.frame = CGRectMake(0, 0, 320.0, 88.0);
self.menu.layer.mask = self.menuMask;
self.menu.layer.masksToBounds = YES;
}
...

而不是在UIKit的帮助下动画,我现在使用CoreAnimation的隐式动画来移动遮罩层:

APPCell.m

...
- (void)swipeLeft
{
self.menuMask.position = CGPointMake(-320.0, 0.0);
}
...

我可以确认是否调用了swipeLeft。我希望面具“不见了”并看到 [UIImage imageNamed:@“cell_back”]] ,当我取消注释 self.menu.layer.mask = self时,我会这样做。 menuMask

解决方案:

我没有在CALayer上设置内容,而是将背景颜色设置为白色。这是我正在使用的代码:

self.menuSubMenuMask = [CALayer layer];
self.menuSubMenuMask.backgroundColor = [[UIColor whiteColor] CGColor];
self.menuSubMenuMask.frame = CGRectMake(320.0, 0.0, 320.0, 88.0);
self.tableCellSubMenu.layer.mask = self.menuSubMenuMask;
self.tableCellSubMenu.layer.masksToBounds = YES;

为了显示应用CALayer的UIImageView,CALayer不能“高于”UIImageView。

3 个答案:

答案 0 :(得分:2)

使用UIVit的UIVits动画比直接使用Core Animation更受限制。特别是你想要制作动画的东西不是UIView的动画属性之一。此外,正如View Programming Guide for iOS中所阐明的那样:

  

注意:如果您的视图托管自定义图层对象(即没有关联视图的图层对象),则必须使用Core Animation为其进行动画处理。

在您的示例中就是这种情况。您已在视图中添加了CALayer,UIKit将无法为您设置动画效果。另一方面,您可以直接使用Core Animation为蒙版图层的动画设置动画。您应该能够使用隐式动画轻松完成此操作,如Core Animation Programming Guide中所述。请注意,从CALayer Animatable Properties列表中该帧不可动画。相反,您应该使用position

答案 1 :(得分:2)

您可以使用CATransition获得所需的内容,但这可能不是您想要的解决方案:

1)首先,为您的图层设置遮罩,就像您一样

2)如果要删除遮罩并显示图像,请使用以下代码:

CATransition* transition = [CATransition animation];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
transition.duration = 1.0;
[mask addAnimation:transition forKey:kCATransition];
imageView.layer.mask.contents = [UIImage imageNamed:@"black.png"].CGImage;

这里的主要技巧 - 我们为遮罩层创建了过渡动画,因此当您更改遮罩层的任何(我不确定任何)属性时,将应用此动画。现在我们将蒙版的内容设置为完全黑色的图像以完全去除蒙版 - 现在我们已经平滑地推动动画,其中我们的蒙面图像向左移动并且未蒙版的图像进入其位置

答案 2 :(得分:2)

最简单的方法是使用CoreAnimation本身:

CGPoint fromPoint = mask.position;
CGPoint toPoint = CGPointMake(fromPoint.x*3.0, fromPoint.y);

mask.position = toPoint; // CoreAnimation animations do *not* persist

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.fromValue = [NSValue valueWithCGPoint:fromPoint];
animation.toValue = [NSValue valueWithCGPoint:toPoint];
animation.duration = 4.0f;

[mask addAnimation:animation forKey:@"position"];