iOS自定义View封装模型后CGContext阴影不显示问题求助
问题排查与修复方案
让我们一步步找出问题所在并解决它:
1. 多余的路径操作导致阴影失效
你在封装后的drawCaption方法里先调用了ctx.addRect(captionRect),但后续并没有使用这个路径(你用的是ctx.fill(captionRect),这个方法会自行创建路径并填充,不需要提前添加路径到上下文)。这个多余的addRect会污染CGContext的当前路径状态,导致阴影没有正确应用到矩形填充操作上。
修复方法:直接移除ctx.addRect(captionRect)这一行代码。
2. 阴影偏移量导致阴影被覆盖
当前你设置的阴影偏移是CGSize(width: 0, height: 0),这会让阴影向矩形四周扩散:
- 顶部的阴影会被View的上边界裁剪掉
- 底部的阴影会被紧接着绘制的条纹完全覆盖(因为条纹的起始y坐标刚好是标题矩形的底部)
所以即使阴影正确绘制了,你也看不到它。如果需求是仅在标题下方显示阴影,应该调整阴影的偏移量,让它向下偏移,比如:
ctx.setShadow(offset: CGSize(width: 0, height: 2), blur: 3, color: UIColor.black.cgColor)
这样阴影会出现在标题矩形的下方,不会被条纹完全覆盖(或者你也可以调整条纹的起始y坐标,让它从caption.captionHeight + 3(blur值)开始,给阴影留出显示空间)。
3. 不必要的泛型使用(可选优化)
CGContext是一个具体的类,不是协议,所以你的StripeDrawable协议里的方法不需要使用泛型<T: CGContext>,直接用CGContext作为参数类型即可,这样代码更简洁,也能避免潜在的类型问题:
protocol StripeDrawable { func drawCaption(in rect: CGRect, using ctx: CGContext) func drawSripes(in rect: CGRect, using ctx: CGContext) }
修复后的完整drawCaption方法
func drawCaption(in rect: CGRect, using ctx: CGContext) { let captionRect = CGRect(x: 0, y: 0, width: rect.width, height: caption.captionHeight) ctx.saveGState() if caption.isCaptionShadowEnabled { // 调整偏移量让阴影显示在标题下方 ctx.setShadow(offset: CGSize(width: 0, height: 2), blur: 3, color: UIColor.black.cgColor) } ctx.setFillColor(caption.captionBackgroundColor.cgColor) ctx.fill(captionRect) let font = UIFont.boldSystemFont(ofSize: caption.captionFontSize) let attribs: [NSAttributedStringKey: Any] = [ .foregroundColor: caption.captionTextColor, .font: font ] caption.captionTitle.center(in: captionRect, attribs: attribs as! [NSAttributedStringKey: NSObject]) ctx.restoreGState() }
为什么未封装的代码能工作?
其实未封装的代码里的ctx.addRect(rect)也是多余的,但可能因为上下文状态在View的draw(_:)方法里更“干净”,或者运气好没有触发路径污染的问题。但本质上,移除这个多余的路径操作才是正确的做法。
内容的提问来源于stack exchange,提问作者yerpy
相关产品推荐
相关产品推荐

