带有切出段和阴影的 UIView

Posted

技术标签:

【中文标题】带有切出段和阴影的 UIView【英文标题】:UIView with cut out segment and shadow 【发布时间】:2017-11-25 21:25:24 【问题描述】:

我的问题如下:我正在尝试从自定义 UIView 中剪下一个片段并将阴影效果应用于此视图。

在自定义 UIView 类中,我这样做了:

创建了两个图层 - 阴影和蒙版。添加了一个阴影层作为此自定义视图的子层。然后我创建了一个新视图,将其遮罩设置为遮罩层并将其作为子视图添加到自定义视图中。

self.backgroundColor = [UIColor clearColor];
CGFloat radius = 40;
float startAngle = -M_PI;
float endAngle = 0;

UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.bounds];

[path moveToPoint:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)+radius/1.8)];
[path addArcWithCenter:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)+radius/1.8) radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];

CAShapeLayer *shadowLayer = [[CAShapeLayer alloc] init];
shadowLayer.frame = self.bounds;
shadowLayer.path = path.CGPath;
shadowLayer.shadowColor = [UIColor grayColor].CGColor;
shadowLayer.shadowOpacity = 0.5;
shadowLayer.shadowRadius = 2;
shadowLayer.masksToBounds = NO;
shadowLayer.shadowOffset = CGSizeMake(2.0, 2.0);
shadowLayer.fillRule = kCAFillRuleEvenOdd;


CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.bounds;
maskLayer.masksToBounds = NO;
maskLayer.path = path.CGPath;
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.fillColor = [UIColor whiteColor].CGColor;

[self.layer addSublayer:shadowLayer];

UIView *view = [[UIView alloc] initWithFrame:self.bounds];
view.backgroundColor = [UIColor whiteColor];
view.layer.mask = maskLayer;
[self addSubview:view];

这就是我想要实现的——

这就是我实际得到的

如果我设置clipToBounds = YES,它将切断所需的阴影效果。

如果我想切一个半圆,那绝对没有问题。因为在这种情况下,半圆路径完全位于视图边界内。

但我确实需要实现第一张图片中显示的结果。 本来想逐行构建路径,但是到了这个圆弧就出现了问题,结果可能不会那么准确。

有没有人知道如何做到这一点? 谢谢!

【问题讨论】:

【参考方案1】:

编辑: 如果问题是路径错误,请不要在代码中使用圆圈和猜测坐标来合成路径。相反,您应该导出坐标实际图稿并将图稿坐标用于曲线。看起来你有一个草图文件,所以最简单的方法是复制并粘贴到paint code,这将为你提供曲线的代码,但如果你没有绘制代码​​(你应该,它这种东西太棒了)你可以从草图中将曲线导出为 SVG。如果您在文本编辑器中打开生成的 SVG,您将看到它是人类可读的 XML,您可以从那里提取贝塞尔曲线的控制点。

【讨论】:

这就是我实际所做的。我创建了两层——阴影层和蒙版层。我添加了阴影层作为自定义视图的子层。在我创建了一个新视图并将其设置为遮罩层之后。它会产生这种奇怪的效果。 谢谢! PaintCode 是一个非常棒的工具!它完成了它的工作,现在一切都几乎完美无缺!唯一的一点是,所有的曲线点都需要调整,以在不同的设备尺寸上产生相同的效果。我应该能够做到这一点:)

以上是关于带有切出段和阴影的 UIView的主要内容,如果未能解决你的问题,请参考以下文章

从背景中切出的透明文本

C++ unordered_map emplace() 函数抛出段错误,我不知道为啥

透明的空心或切出的圆圈

MATLAB / Octave:从图像中切出很多圆圈

如何在底部和所有侧面创建带有盒子阴影的容器

拖动带有阴影的自定义 UIView - 大小重置和阴影消失