You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 11:57:18