简体   繁体   English

CALayer面具无法正常工作

[英]CALayer mask not working correctly

I am trying to mask a UIView to an image using it's layer's mask property. 我试图使用它的图层的掩码属性将UIView屏蔽到图像。 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 这是我试图用来掩盖视图的图像: http//cl.ly/0a300G2r133V

One possibility is that the system's not actually using setFrame: to set your view's geometry. 一种可能性是系统实际上并没有使用setFrame:来设置视图的几何体。 It can use setCenter: and setBounds: . 它可以使用setCenter: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. 另一种可能性是系统根本没有设置视图的几何体,并且在添加遮罩层之前,只在[super initWithFrame:frame]调用中设置了一次。

Anyway, instead of overriding setFrame: , you should override layoutSubviews : 无论如何,你应该覆盖layoutSubviews而不是覆盖setFrame:

- (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. 我不确定为什么只使用普通的CALayer不起作用,但这增加了与可伸缩图像配合良好的好处。

You can override the UIView drawRect() method for its custom appearance on the screen. 您可以在屏幕上覆盖UIView drawRect()方法的自定义外观。 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. 它会使您的视图在imageFrame区域中透明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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