打造可滑动切换的顶部TabBar
SwiftUI技能UPUP:打造可滑动切换的顶部TabBar
在SwiftUI应用中,实现一个带有可滑动切换的顶部TabBar是一个常见的需求。本文将介绍如何使用SwiftUI创建一个具有这种功能的界面。
准备工作
首先,我们需要定义一个 ContentView
结构体,其中包含了一些必要的状态变量和数据。具体代码如下:
struct ContentView: View {
@State private var selectedTabIndex = 0
@State private var selectedTabID: Int? = nil
let tabTitles = ["Tab 1", "Tab 2", "Tab 3", "Tab 4", "Tab 5", "Tab 6", "Tab 7", "Tab 8", "Tab 9", "Tab 10"]
var body: some View {
// 界面布局代码在这里
}
}
创建界面布局
我们使用 GeometryReader 来获取屏幕的尺寸,并在垂直方向上创建一个 VStack,在其中包含一个水平滚动的 ScrollView 和一个 TabView,分别用于显示选项卡和选项卡内容。
GeometryReader(content: { geometry in
VStack (spacing: 0) {
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 20) {
ForEach(0..<tabTitles.count, id: \.self) { index in
// 每个选项卡按钮的代码
}
}
}
.scrollPosition(id: $selectedTabID, anchor: .center)
.frame(height: 50)
// Content views for each tab
TabView(selection: $selectedTabIndex) {
ForEach(0..<tabTitles.count, id: \.self) { index in
// 每个选项卡内容的代码
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .never))
}
})
实现交互功能
最后,我们使用 Button 和 onChange 等函数来实现选项卡之间的切换功能,并添加一些动画效果,提升用户体验。
.onChange(of: selectedTabIndex) { oldValue, newValue in
withAnimation {
selectedTabIndex = newValue
selectedTabID = newValue
}
}
完整源码
import SwiftUI
struct ContentView: View {
@State private var selectedTabIndex = 0
@State private var selectedTabID: Int? = nil
let tabTitles = ["Tab 1", "Tab 2", "Tab 3", "Tab 4", "Tab 5", "Tab 6", "Tab 7", "Tab 8", "Tab 9", "Tab 10"]
var body: some View {
GeometryReader(content: { geometry in
VStack (spacing: 0) {
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 20) {
ForEach(0..<tabTitles.count, id: \.self) { index in
Button(action: {
withAnimation {
selectedTabIndex = index
selectedTabID = index
}
}) {
Text(tabTitles[index])
.font(.headline)
.foregroundColor(selectedTabIndex == index ? .red : .black)
.frame(width: 60)
}
}
}
}
.scrollPosition(id: $selectedTabID, anchor: .center)
.frame(height: 50)
// Content views for each tab
TabView(selection: $selectedTabIndex) {
ForEach(0..<tabTitles.count, id: \.self) { index in
ZStack {
Color(uiColor: .systemGray6)
Text("Content for \(tabTitles[index])")
.font(.title)
.tag(index)
}
.ignoresSafeArea(edges: .bottom)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .never))
}
})
.ignoresSafeArea(edges: .bottom)
.onChange(of: selectedTabIndex) { oldValue, newValue in
withAnimation {
selectedTabIndex = newValue
selectedTabID = newValue
}
}
}
}
#Preview {
ContentView()
}
License:
CC BY 4.0