Skip to content

Instantly share code, notes, and snippets.

@enomoto
Created October 18, 2023 06:40
Show Gist options
  • Save enomoto/adce327a98cbc11660a738afd5b2299a to your computer and use it in GitHub Desktop.
Save enomoto/adce327a98cbc11660a738afd5b2299a to your computer and use it in GitHub Desktop.
SimpleTabView with SwiftUI
import SwiftUI
struct ContentView: View {
var body: some View {
MyTabView(
tabContents: [
.init(id: 0, title: "foo", content: PageView(title: "foo", color: .yellow)),
.init(id: 1, title: "bar", content: PageView(title: "bar", color: .red)),
.init(id: 2, title: "baz", content: PageView(title: "baz", color: .brown)),
.init(id: 3, title: "qux", content: PageView(title: "qux", color: .purple)),
.init(id: 4, title: "quux", content: PageView(title: "quux", color: .gray)),
]
)
}
}
struct PageView: View {
var title: String
var color: Color
var body: some View {
VStack(spacing: 0) {
Text(title)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(color)
}
}
}
struct MyTabView<Content: View>: View {
@State var selection: Int = 0
var tabContents: [TabContent<Content>]
var body: some View {
VStack(spacing: 0) {
MyTabBarView(
tabBars: tabContents.map {($0.id, $0.title )},
selection: $selection
)
.frame(height: 44)
TabContentsView(
selection: $selection,
tabContents: tabContents
)
}
}
}
struct TabContent<Content: View>: Identifiable {
var id: Int
var title: String
var content: Content
}
struct MyTabBarView: View {
var tabBars: [(id: Int, title: String)]
@Binding var selection: Int
var body: some View {
HStack {
ForEach(tabBars, id: \.id) { tabBar in
Button {
selection = tabBar.id
} label: {
HStack {
Text("\(tabBar.title)")
Text("\(tabBar.id)")
}
.foregroundColor(.black)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(8)
.background(
Group {
selection == tabBar.id ? Color.green : Color.white
}
)
}
}
}
}
}
struct TabContentsView<Content: View>: View {
@Binding var selection: Int
var tabContents: [TabContent<Content>]
var body: some View {
TabView(selection: $selection) {
ForEach(tabContents) { tabContent in
tabContent.content
}
}
.tabViewStyle(.page(indexDisplayMode: .never))
.animation(.easeInOut, value: selection)
}
}
#Preview {
ContentView()
}
@enomoto
Copy link
Author

enomoto commented Oct 18, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment