115 lines
3.0 KiB
Swift
115 lines
3.0 KiB
Swift
import SwiftUI
|
||
|
||
enum AppTab: String, CaseIterable, Identifiable {
|
||
case home
|
||
case movie
|
||
case series
|
||
case variety
|
||
case anime
|
||
case settings
|
||
|
||
var id: String { rawValue }
|
||
|
||
var title: String {
|
||
switch self {
|
||
case .home: return "首页"
|
||
case .movie: return "电影"
|
||
case .series: return "电视剧"
|
||
case .variety: return "综艺"
|
||
case .anime: return "动漫"
|
||
case .settings: return "设置"
|
||
}
|
||
}
|
||
|
||
var icon: String {
|
||
switch self {
|
||
case .home: return "house"
|
||
case .movie: return "film"
|
||
case .series: return "tv"
|
||
case .variety: return "theatermasks"
|
||
case .anime: return "sparkles"
|
||
case .settings: return "gearshape"
|
||
}
|
||
}
|
||
|
||
var category: ContentCategory? {
|
||
switch self {
|
||
case .movie: return .movie
|
||
case .series: return .series
|
||
case .variety: return .variety
|
||
case .anime: return .anime
|
||
default: return nil
|
||
}
|
||
}
|
||
}
|
||
|
||
struct AppNavigation: View {
|
||
@State private var selectedTab: AppTab = .home
|
||
// 持有各 tab 的 ViewModel,切换 tab 不丢失状态
|
||
@State private var homeVM = HomeViewModel()
|
||
@State private var movieVM = BrowseViewModel()
|
||
@State private var seriesVM = BrowseViewModel()
|
||
@State private var varietyVM = BrowseViewModel()
|
||
@State private var animeVM = BrowseViewModel()
|
||
|
||
var body: some View {
|
||
#if os(macOS)
|
||
sidebarLayout
|
||
#elseif os(visionOS)
|
||
sidebarLayout
|
||
#else
|
||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||
sidebarLayout
|
||
} else {
|
||
tabLayout
|
||
}
|
||
#endif
|
||
}
|
||
|
||
private var tabLayout: some View {
|
||
TabView(selection: $selectedTab) {
|
||
ForEach(AppTab.allCases) { tab in
|
||
NavigationStack {
|
||
tabContent(for: tab)
|
||
}
|
||
.tabItem {
|
||
Label(tab.title, systemImage: tab.icon)
|
||
}
|
||
.tag(tab)
|
||
}
|
||
}
|
||
}
|
||
|
||
private var sidebarLayout: some View {
|
||
NavigationSplitView {
|
||
List(AppTab.allCases, selection: $selectedTab) { tab in
|
||
Label(tab.title, systemImage: tab.icon)
|
||
.tag(tab)
|
||
}
|
||
.navigationTitle("低端影视")
|
||
} detail: {
|
||
NavigationStack {
|
||
tabContent(for: selectedTab)
|
||
}
|
||
}
|
||
}
|
||
|
||
@ViewBuilder
|
||
private func tabContent(for tab: AppTab) -> some View {
|
||
switch tab {
|
||
case .home:
|
||
HomeView(viewModel: homeVM)
|
||
case .movie:
|
||
BrowseView(category: .movie, viewModel: movieVM)
|
||
case .series:
|
||
BrowseView(category: .series, viewModel: seriesVM)
|
||
case .variety:
|
||
BrowseView(category: .variety, viewModel: varietyVM)
|
||
case .anime:
|
||
BrowseView(category: .anime, viewModel: animeVM)
|
||
case .settings:
|
||
SettingsView()
|
||
}
|
||
}
|
||
}
|