如何为带遮罩的视图添加阴影?梯形视图阴影添加失败求助
解决梯形视图的阴影不显示问题
嘿,我帮你找到了问题所在,你的梯形阴影没出效果主要是两个关键问题,咱们一步步来搞定它:
问题分析
- 你把
shadowPath设置成了梯形路径的bounds圆角矩形,这和实际的梯形形状完全不符,就算阴影能显示,也是矩形的,不是你要的梯形阴影 - 当你给
whiteView.layer设置mask = trapezoidLayer时,遮罩会裁剪掉whiteView.layer的所有内容——包括阴影,因为阴影是在视图边界外绘制的,遮罩会把超出梯形路径的部分全部切掉
修复方案
方案一:直接给梯形形状层添加阴影(推荐)
这种方法更直接,不用依赖whiteView的遮罩,直接创建带阴影的梯形层:
let trapezoidPath = UIBezierPath() trapezoidPath.move(to: CGPoint(x: 0, y: 0)) trapezoidPath.addLine(to: CGPoint(x: Constants.padding, y: bounds.maxY - 10)) trapezoidPath.addLine(to: CGPoint(x: titleLabel.bounds.width + Constants.padding, y: bounds.maxY - 10)) trapezoidPath.addLine(to: CGPoint(x: titleLabel.bounds.width + 2 * Constants.padding, y: 0)) trapezoidPath.close() // 重要:必须闭合路径,否则形状不完整! let trapezoidLayer = CAShapeLayer() trapezoidLayer.path = trapezoidPath.cgPath trapezoidLayer.fillColor = UIColor.white.cgColor // 这里设置梯形的填充色,替代原来的whiteView // 给梯形层添加阴影 trapezoidLayer.shadowPath = trapezoidPath.cgPath trapezoidLayer.shadowRadius = 15 trapezoidLayer.shadowOffset = .zero trapezoidLayer.shadowOpacity = 0.4 trapezoidLayer.shadowColor = UIColor.red.cgColor // 将梯形层添加到父视图中 whiteView.layer.addSublayer(trapezoidLayer) // 如果原来的whiteView不需要了,可以移除它,或者调整视图层级确保梯形层在正确位置
方案二:用容器视图承载阴影(保留whiteView的遮罩)
如果你一定要保留whiteView的遮罩逻辑,可以给它套一个容器视图,把阴影加在容器上:
// 创建容器视图,用来承载阴影 let shadowContainer = UIView(frame: whiteView.frame) whiteView.superview?.addSubview(shadowContainer) shadowContainer.addSubview(whiteView) // 绘制梯形路径 let trapezoidPath = UIBezierPath() trapezoidPath.move(to: CGPoint(x: 0, y: 0)) trapezoidPath.addLine(to: CGPoint(x: Constants.padding, y: whiteView.bounds.maxY - 10)) trapezoidPath.addLine(to: CGPoint(x: titleLabel.bounds.width + Constants.padding, y: whiteView.bounds.maxY - 10)) trapezoidPath.addLine(to: CGPoint(x: titleLabel.bounds.width + 2 * Constants.padding, y: 0)) trapezoidPath.close() // 闭合路径 let trapezoidLayer = CAShapeLayer() trapezoidLayer.path = trapezoidPath.cgPath whiteView.layer.mask = trapezoidLayer // 给容器视图添加阴影,阴影路径和梯形路径一致 shadowContainer.layer.shadowPath = trapezoidPath.cgPath shadowContainer.layer.shadowRadius = 15 shadowContainer.layer.shadowOffset = .zero shadowContainer.layer.shadowOpacity = 0.4 shadowContainer.layer.shadowColor = UIColor.red.cgColor shadowContainer.layer.masksToBounds = false
关键注意点
- 务必调用
trapezoidPath.close()闭合路径,否则形状是开放的,阴影会出现异常 - 遮罩(mask)会裁剪掉所有超出路径的内容,所以不能给被遮罩的视图层加阴影,要么把阴影加在形状层自身,要么用容器视图承载阴影
shadowPath必须和实际的形状路径完全一致,不能用路径的bounds矩形,否则阴影形状会不符合预期
内容的提问来源于stack exchange,提问作者Artyom Vlasenko
相关产品推荐
相关产品推荐

