一,代码:
import SwiftUI
struct ContentView3: View {
@State private var selectedTab = 0
var body: some View {
ZStack(alignment: .bottom) {
// 使用 Page 样式实现左右滑动动画
TabView(selection: $selectedTab) {
HomeView2()
.tag(0)
ListView2()
.tag(1)
AboutView()
.tag(2)
}
// 核心设置:开启分页滑动模式
// indexDisplayMode: .never 隐藏底部的原生小圆点
.tabViewStyle(.page(indexDisplayMode: .never))
.animation(.easeInOut, value: selectedTab) // 点击切换时的平滑动画
// 自定义底部栏(因为 .page 模式下原生 TabBar 会消失)
customTabBar
}
.ignoresSafeArea(.keyboard) // 避免键盘弹出影响布局
}
// 抽离出的自定义底部栏
var customTabBar: some View {
HStack {
TabBarItem(title: "首页", icon: "house.fill", index: 0, selection: $selectedTab)
Spacer()
TabBarItem(title: "列表", icon: "list.bullet", index: 1, selection: $selectedTab)
Spacer()
TabBarItem(title: "关于", icon: "person.circle", index: 2, selection: $selectedTab)
}
.padding(.horizontal, 40)
.frame(height: 100) // 这里调高高度
.background(Color(.systemGray6))
.shadow(color: .black.opacity(0.1), radius: 10, y: -5)
}
}
// 按钮组件
struct TabBarItem: View {
let title: String
let icon: String
let index: Int
@Binding var selection: Int
var body: some View {
Button {
withAnimation { selection = index }
} label: {
VStack(spacing: 4) {
Image(systemName: icon).font(.system(size: 22))
Text(title).font(.caption2)
}
.foregroundColor(selection == index ? .blue : .gray)
}
}
}
// --- 子页面定义 ---
struct HomeView2: View {
var body: some View {
VStack {
Text("这是首页")
.font(.headline)
Image(systemName: "globe") // 使用系统图标
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 200, height: 200)
.foregroundColor(.blue)
}
}
}
struct ListView2: View {
var body: some View {
VStack {
Text("内容列表")
.font(.headline)
Image(systemName: "doc.text.magnifyingglass")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 200, height: 200)
.foregroundColor(.green)
}
}
}
struct AboutView: View {
var body: some View {
VStack {
Text("关于我们")
.font(.headline)
Image(systemName: "info.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 200, height: 200)
.foregroundColor(.orange)
}
}
}
二,测试效果:
![image]()