SwiftUI如何绘制类似Dynamic Island的顶部弧形?
复刻Dynamic Island实时活动顶部弧形的SwiftUI实现方案
问题分析
你当前的实现存在两个核心问题:
- 用
Path绘制的是标准半圆:因为圆心设置在视图中心,且仅绘制了弧形路径未闭合,无法得到Dynamic Island那种“扁弧形+底部圆角”的复合形状。 Circle裁剪的方式局限性大:trim基于圆形比例生成弧形,无法灵活调整弧形的扁平程度,也没法直接添加底部的圆角直线段。
解决方案:自定义Shape实现复合弧形
通过自定义Shape,可以精准控制弧形的弧度、底部圆角以及整体形状的闭合,完美复刻目标样式:
struct DynamicIslandTopArc: Shape { // 底部两端的圆角半径 let cornerRadius: CGFloat // 弧形的高度(控制弧形的扁平程度,值越小越扁) let arcHeight: CGFloat func path(in rect: CGRect) -> Path { var path = Path() // 左下角圆角起点 path.move(to: CGPoint(x: rect.minX + cornerRadius, y: rect.maxY)) // 绘制左下角圆角 path.addArc(center: CGPoint(x: rect.minX + cornerRadius, y: rect.maxY - cornerRadius), radius: cornerRadius, startAngle: .degrees(90), endAngle: .degrees(180), clockwise: false) // 左侧直线连接到弧形起点 path.addLine(to: CGPoint(x: rect.minX, y: rect.minY + arcHeight)) // 绘制顶部弧形(圆心在弧形底部中点,半径为视图宽度的一半) path.addArc(center: CGPoint(x: rect.midX, y: rect.minY + arcHeight), radius: rect.width / 2, startAngle: .degrees(180), endAngle: .degrees(0), clockwise: false) // 右侧直线连接到右下角圆角起点 path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - cornerRadius)) // 绘制右下角圆角 path.addArc(center: CGPoint(x: rect.maxX - cornerRadius, y: rect.maxY - cornerRadius), radius: cornerRadius, startAngle: .degrees(0), endAngle: .degrees(90), clockwise: false) // 闭合路径形成完整形状 path.closeSubpath() return path } }
使用示例
调整cornerRadius和arcHeight参数可以匹配不同的设计需求:
DynamicIslandTopArc(cornerRadius: 16, arcHeight: 20) .fill(LinearGradient(colors: [.blue, .cyan], startPoint: .leading, endPoint: .trailing)) .frame(height: 60) .padding(.horizontal, 20)
参数说明
cornerRadius:控制底部左右两端的圆角大小,和苹果设计系统的圆角规范对齐即可。arcHeight:控制顶部弧形的凸起高度,值越小弧形越扁平,值越大越接近半圆。
内容的提问来源于stack exchange,提问作者SantiOch
相关产品推荐
相关产品推荐

