I am using this code proposed by Bartosz to add a mask to an UIImageView. It works fine.
#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;
In addition, I want to animate the mask, e.g. sliding the mask to the right, so that at the end of the animation, the mask is not applied to the UIImageView any more.
In my specific case, the mask uses a fully transparent image, so the UIImageView is not visible at the initial state (which works fine), but is expected to be so at the end of the animation. However, the idea may be reused to any other use case were masks need to be animated.
The idea is to manipulate the x-origin portion of the frame of the mask. So, I came up with this code:
[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){}];
Unfortunately, the mask is applied to the whole UIImageView at any time, it's not sliding to the right.
UPDATE 1:
This is the code I am actually using the set up the view and mask: It's a UITableViewCell.
APPCell.m (APPCell.h "extends" 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;
}
...
Instead of animating with the help of UIKit, I am now using implicit animation of CoreAnimation to move the mask layer:
APPCell.m
...
- (void)swipeLeft
{
self.menuMask.position = CGPointMake(-320.0, 0.0);
}
...
I can confirm that swipeLeft is called. I expect the mask "to be gone" and to see the [UIImage imageNamed:@"cell_back"]], which I do when I uncomment self.menu.layer.mask = self.menuMask.
Solution:
Instead of setting the content on the CALayer, I set the background color to white. This is the code I am using:
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;
In order to show the UIImageView the CALayer is applied to, the CALayer must NOT be "above" the UIImageView.
maskFrame = imageView.layer.mask.frame;
and the expected reverse two lines below that? – Tommy