Swift中为可展开UIView添加顶部中心透明半圆的实现指引
实现视图顶部中心透明半圆的方案
嘿,很高兴听到你已经搞定了视图展开的核心功能!关于顶部中心的透明半圆,这里有几个简单易实现的方案,适配不同平台的场景:
方案一:自定义视图裁剪(iOS/Android 原生开发通用思路)
这个方案通过绘制路径来裁剪视图,是最灵活的方式,适配视图尺寸变化的场景。
iOS(Swift 示例)
创建一个自定义视图类,重写layoutSubviews方法来生成带半圆缺口的遮罩:
class NotchTopView: UIView { // 可根据需求调整半圆半径 let halfCircleRadius: CGFloat = 20 override func layoutSubviews() { super.layoutSubviews() // 1. 创建视图完整区域的路径 let fullPath = UIBezierPath(rect: bounds) // 2. 创建顶部中心的半圆路径(顺时针绘制下半圆,用来挖空) let notchCenter = CGPoint(x: bounds.midX, y: 0) let notchPath = UIBezierPath(arcCenter: notchCenter, radius: halfCircleRadius, startAngle: .pi, endAngle: 0, clockwise: false) // 3. 合并路径并启用奇偶填充规则,实现挖空效果 fullPath.append(notchPath) fullPath.usesEvenOddFillRule = true // 4. 设置遮罩层 let maskLayer = CAShapeLayer() maskLayer.path = fullPath.cgPath maskLayer.fillRule = .evenOdd layer.mask = maskLayer } }
把你现有的蓝、绿、橙视图替换成这个自定义类,就能自动生成顶部的透明半圆了。视图尺寸变化时(比如展开动画),layoutSubviews会重新计算路径,适配新的尺寸。
Android(Kotlin 示例)
自定义View重写onDraw方法,用Path实现类似的裁剪:
class NotchTopView(context: Context, attrs: AttributeSet?) : View(context, attrs) { private val halfCircleRadius = 20f private val path = Path() override fun onDraw(canvas: Canvas) { path.reset() // 添加完整视图区域 path.addRect(0f, 0f, width.toFloat(), height.toFloat(), Path.Direction.CW) // 添加顶部半圆区域(用来挖空) path.addArc( width/2 - halfCircleRadius, -halfCircleRadius, width/2 + halfCircleRadius, halfCircleRadius, 180f, 180f ) // 设置奇偶填充规则 path.fillType = Path.FillType.EVEN_ODD canvas.clipPath(path) // 绘制你的视图背景色(蓝/绿/橙) canvas.drawColor(if (tag == "blue") Color.BLUE else if (tag == "green") Color.GREEN else Color.ORANGE) } }
方案二:图片叠加(快速实现,适合静态尺寸视图)
如果你的视图尺寸固定,这个方式更省事:
- 用设计工具(比如Figma、Sketch)导出一张和视图背景色一致的图片,顶部中心留一个透明半圆缺口
- 将这张图片作为子视图放在目标视图的顶部,宽度和视图一致,高度等于半圆的直径
- 这样视觉上就呈现出视图顶部有透明半圆的效果,原理是上层图片的缺口露出了下方的内容
方案三:CSS 实现(Web 前端场景)
如果是网页端的视图,可以用伪元素+阴影技巧实现:
.color-view { position: relative; width: 200px; height: 300px; background-color: #007aff; /* 蓝色示例 */ overflow: hidden; } .color-view::before { content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 40px; /* 半圆直径 */ height: 20px; /* 半圆半径 */ border-radius: 0 0 20px 20px; /* 阴影颜色要和视图的父容器背景色一致,模拟透明效果 */ box-shadow: 0 0 0 9999px #ffffff; }
只需要给你的蓝、绿、橙视图加上.color-view类,调整阴影颜色匹配父背景即可。
内容的提问来源于stack exchange,提问作者Muthu Sabarinathan
相关产品推荐
相关产品推荐

