设置 CALayer maskToBounds 导致图层消失

Posted

技术标签:

【中文标题】设置 CALayer maskToBounds 导致图层消失【英文标题】:Setting CALayer maskToBounds causing layer to disappear 【发布时间】:2014-09-26 13:08:48 【问题描述】:

我正在尝试创建一个根据特定百分比填充的圆圈。这是我想要的效果图片:

我有一个 UIView,并为此添加了一个绘制圆圈的 CAShapeLayer。然后,我将另一个 UIShapeLayer 创建为正方形,以匹配包含圆形的 UIView。然后根据图设置这个的高度。因此,如果正方形的高度为 100 像素且值为 10%,那么我将正方形设置为 10 像素,以便填充 10% 的圆。

下图显示了 50% 的圆圈被填充。如您所见,它覆盖了 UIView 以及圆圈​​。但是,当我尝试将 CAShapeLayer 设置为掩码到边界 (circle.maskToBounds) 时,完整的圆与我添加的正方形一起消失,因为它是子视图。

这是我的代码:

- (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
    [self drawCircleInView:view];
    [self.view addSubview:view];

- (void)drawCircleInView:(UIView *)v

    // Set up the shape of the circle
    int radius = v.frame.size.height / 2;
    CAShapeLayer *circle = [CAShapeLayer layer];
    // Make a circular shape
    circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2*radius, 2*radius)
                                         cornerRadius:radius].CGPath;

    // Center the shape in self.view
    circle.position = CGPointMake(CGRectGetMidX(v.bounds)-radius,
                              CGRectGetMidY(v.bounds)-radius);

    // Configure the apperence of the circle
    circle.fillColor = [UIColor blueColor].CGColor;
    circle.strokeColor = [UIColor clearColor].CGColor;
    circle.lineWidth = 5;
    circle.masksToBounds = YES;  // HERE IS THE LINE OF CODE THAT MAKES THE CIRCLE DISAPPEAR

    CAShapeLayer *sublayer = [CAShapeLayer layer];
    sublayer.backgroundColor = [UIColor orangeColor].CGColor;
    sublayer.opacity = .5f;
    sublayer.frame = CGRectMake(0, 100, 200, 100);
    [circle addSublayer:sublayer];


    // Add to parent layer
    [v.layer addSublayer:circle];

我想知道为什么设置 circle.masksToBounds = YES 会使圆圈和子图层完全消失。我的理解是,通过设置它应该只在圆圈上显示子层。

非常感谢。

【问题讨论】:

在你的圈层设置maskLayer怎么样?它认为这是一种更好的方法。 【参考方案1】:

试试这个:

- (void)drawCircleInView:(UIView *)v 
    // Set up the shape of the circle
    CGSize size = v.bounds.size;
    CALayer *layer = [CALayer layer];
    layer.frame = v.bounds;
    layer.backgroundColor = [UIColor blueColor].CGColor;

    CALayer *sublayer = [CALayer layer];
    sublayer.frame = CGRectMake(0, size.height/2, size.width, size.height/2);
    sublayer.backgroundColor = [UIColor orangeColor].CGColor;
    sublayer.opacity = .5f;

    CAShapeLayer *mask = [CAShapeLayer layer];
    mask.frame = v.bounds;
    mask.path = [UIBezierPath bezierPathWithOvalInRect:v.bounds].CGPath;
    mask.fillColor = [UIColor blackColor].CGColor;
    mask.strokeColor = [UIColor clearColor].CGColor;

    [layer addSublayer:sublayer];
    [layer setMask:mask];

    // Add to parent layer
    [v.layer addSublayer:layer];

    maskToBounds 是“to bounds”你没有设置boundsframe。 不是必须的,但最好设置frame of CAShapeLayer,以免造成不必要的混淆。 bounds 是矩形,而不是 CAShapeLayer 的形状。改用mask 图层按形状遮罩。 circlesublayer 不需要是 CAShapeLayer,因为它会被 shape mask 层掩盖。

【讨论】:

感谢这个 rintaro。它完美地工作。并感谢您的额外解释。【参考方案2】:

要实现这一点,请使用中心圆透明的方形图像。喜欢这张图片

如何使用此图像来实现此效果 -

首先添加一个正方形图层(颜色较浅/或非填充颜色)。在上面添加一个带有健全矩形填充颜色的图层。最重要的是放置此图像。并更改具有填充颜色的中间层的框架以达到所需的效果

【讨论】:

感谢 Viper 的建议。我选择了 rintaro 的答案,因为这些圆圈将显示在一个图案上。据我了解,这只有在图像的不透明部分与背景匹配时才有效。 使用最适合你的东西.. :)

以上是关于设置 CALayer maskToBounds 导致图层消失的主要内容,如果未能解决你的问题,请参考以下文章

WPFのclipToBounds与maskToBounds的区别

WPFのclipToBounds与maskToBounds的区别

clip to bounds 和mask to bounds的区别

使用将 maskToBounds 设置为 true 和cornerRadius 不会更改视图

如何在 CAShapeLayer(Rounded-Recr 角 UIView)上设置 maskToBounds 效果?

UITableViewCell 在子视图性能问题中调用 .layer.maskToBounds = YES [重复]