如何在SwiftUI的TabView中添加底部中央曲线?
SwiftUI实现TabView底部中央曲线效果
要在TabView底部中央添加固定曲线,由于无法直接修改TabView的shape属性,我们可以通过自定义Shape叠加或替换tabBar背景的方式实现,以下是适配你现有代码的解决方案:
实现步骤
1. 定义曲线Shape
创建一个底部中央带向上凸曲线的自定义Shape:
import SwiftUI struct CurveShape: Shape { func path(in rect: CGRect) -> Path { var path = Path() // 绘制底部带中央凸曲线的路径 path.move(to: CGPoint(x: rect.minX, y: rect.minY)) path.addLine(to: CGPoint(x: rect.midX - 40, y: rect.minY)) // 贝塞尔曲线控制弧度,可调整control点y值改变弧度大小 path.addQuadCurve(to: CGPoint(x: rect.midX + 40, y: rect.minY), control: CGPoint(x: rect.midX, y: rect.minY - 20)) path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY)) path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY)) path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY)) path.closeSubpath() return path } }
2. 整合到现有TabView代码
针对不同iOS版本提供两种实现方案:
方案一:iOS 16+ 适配(更简洁)
利用tabBarBackground直接替换tabBar背景:
struct DashboardTabBarView: View { @State private var selection: String = "home" struct Item { let title: String let color: Color let icon: String } @State var items = [ Item(title: "cart", color: .red, icon: "cart"), Item(title: "home", color: .blue, icon: "house"), Item(title: "car", color: .green, icon: "car"), ] var body: some View { TabView(selection: $selection) { ForEach(items, id: \.title) { item in item.color .tabItem { Image(systemName: item.icon) Text(item.title) } } } // 自定义tabBar背景,曲线始终居中 .tabBarBackground { CurveShape() .fill(Color.white) // 可替换为你需要的背景色 .edgesIgnoringSafeArea(.bottom) } .onChange(of: selection) { title in let target = 1 if var i = items.firstIndex(where: { $0.title == title }) { if i > target { i += 1 } items.move(fromOffsets: IndexSet(integer: target), toOffset: i) } } } }
方案二:兼容iOS 15及以下
通过ZStack叠加曲线视图覆盖tabBar区域:
struct DashboardTabBarView: View { @State private var selection: String = "home" struct Item { let title: String let color: Color let icon: String } @State var items = [ Item(title: "cart", color: .red, icon: "cart"), Item(title: "home", color: .blue, icon: "house"), Item(title: "car", color: .green, icon: "car"), ] var body: some View { ZStack(alignment: .bottom) { TabView(selection: $selection) { ForEach(items, id: \.title) { item in item.color .tabItem { Image(systemName: item.icon) Text(item.title) } } } // 叠加曲线视图,覆盖tabBar区域 CurveShape() .fill(Color.white) .frame(height: 80) // 高度覆盖tabBar及安全区 .edgesIgnoringSafeArea(.bottom) } .onChange(of: selection) { title in let target = 1 if var i = items.firstIndex(where: { $0.title == title }) { if i > target { i += 1 } items.move(fromOffsets: IndexSet(integer: target), toOffset: i) } } } }
调整说明
- 曲线弧度:修改
CurveShape中贝塞尔曲线的control点y值(如rect.minY - 20),数值越大弧度越明显 - 曲线宽度:调整
midX ± 40的数值,数值越大曲线覆盖范围越宽 - 背景颜色:将
fill(Color.white)替换为你的tabBar主题色即可
内容的提问来源于stack exchange,提问作者Rehan Ali Khan
相关产品推荐
相关产品推荐

