简体   繁体   中英

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

One possibility is that the system's not actually using setFrame: to set your view's geometry. It can use setCenter: and setBounds: . Another possibility is that the system is not setting your view's geometry at all, and it's only being set once, in the [super initWithFrame:frame] call, before you add the mask layer.

Anyway, instead of overriding setFrame: , you should override layoutSubviews :

- (void)layoutSubviews {
    [super layoutSubviews];
    self.layer.mask.frame = self.bounds;
}

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.

You can override the UIView drawRect() method for its custom appearance on the screen. Try to use following approach.

//code for drawRect()

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddRect(context,ImageFrame);
CGContextClip(context);
CGContextClearRect(context,ImageFrame);
[super drawRect:rect];

It will make your view transparent in your imageFrame area.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM