2

我正在使用 Bartosz 提出的此代码向 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 的“上方”。

4

3 回答 3

2

使用 UIViews 的 UIKit 的动画比直接使用 Core Animation 受限得多。特别是你试图动画的不是 UIView 的动画属性之一。此外,正如View Programming Guide for iOS中所阐明的那样:

注意:如果您的视图托管自定义图层对象(即没有关联视图的图层对象),您必须使用核心动画来动画它们的任何更改。

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

于 2012-11-17T03:46:48.037 回答
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;

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

于 2012-11-22T08:48:41.920 回答
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"];
于 2012-11-22T20:04:58.867 回答