Search code examples
ioscocoa-touchcore-animationcalayer

CALayer mask not working correctly


I am trying to mask a UIView to an image using it's layer's mask property. I have seen countless examples that say, "it's just that easy". However, after quite a bit of tweaking, I cannot seem to reproduce the results described. Setting the layer mask only makes the view disappear. Here is the code that I am using:

- (void)setMaskImage:(UIImage *)maskImage
{
    _maskImage = maskImage;

    self.layer.mask.contents = (__bridge id)(_maskImage.CGImage);
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self != nil) {
        self.layer.mask = [CALayer layer];
    }

    return self;
}

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];

    self.layer.mask.frame = self.layer.bounds;
}

And here is the image that I am trying to use to mask the view: http://cl.ly/0a300G2r133V


Solution

  • The following works as expected:

    - (void)setMaskImage:(UIImage *)maskImage
    {
        if (_maskView == nil) {
            _maskView = [[UIImageView alloc] initWithImage:maskImage];
            _maskView.frame = self.bounds;
            self.layer.mask = _maskView.layer;
        } else {
            _maskView.image = maskImage;
        }
    }
    
    - (UIImage *)maskImage
    {
        return _maskView.image;
    }
    
    - (void)setBounds:(CGRect)bounds
    {
        [super setBounds:bounds];
    
        _maskView.frame = self.bounds;
    }
    

    I'm not sure why just using a plain CALayer wasn't working, but this adds the bonus of working well with stretchable images.