Files
e-party-iOS/yana/MVVM/MainPage.swift
edwinQQQ 428aa95c5e feat: 更新Swift助手样式规则和应用结构
- 在swift-assistant-style.mdc中添加项目背景、代码结构、命名规范、Swift最佳实践、UI开发、性能、安全性、测试与质量、核心功能、开发流程、App Store指南等详细规则。
- 在yanaApp.swift中将SplashView替换为Splash,简化应用结构。
2025-08-06 14:12:20 +08:00

168 lines
4.3 KiB
Swift

import SwiftUI
// MARK: - Main ViewModel
@MainActor
class MainViewModel: ObservableObject {
// MARK: - Published Properties
@Published var selectedTab: Tab = .feed
@Published var isLoggedOut: Bool = false
// MARK: - Callbacks
var onLogout: (() -> Void)?
// MARK: - Enums
enum Tab: String, CaseIterable {
case feed = "feed"
case me = "me"
var title: String {
switch self {
case .feed:
return "Feed"
case .me:
return "Me"
}
}
var iconName: String {
switch self {
case .feed:
return "list.bullet"
case .me:
return "person.circle"
}
}
}
// MARK: - Public Methods
func onAppear() {
debugInfoSync("🚀 MainView onAppear")
debugInfoSync(" 当前selectedTab: \(selectedTab)")
}
func onTabChanged(_ newTab: Tab) {
selectedTab = newTab
debugInfoSync("🔄 MainView selectedTab changed: \(newTab)")
}
func onLogoutTapped() {
isLoggedOut = true
onLogout?()
}
}
// MARK: - Main View
struct MainPage: View {
@StateObject private var viewModel = MainViewModel()
let onLogout: () -> Void
var body: some View {
NavigationStack {
GeometryReader { geometry in
ZStack {
//
LoginBackgroundView()
//
mainContentView(geometry: geometry)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(.bottom, 80) //
// -
VStack {
Spacer()
bottomTabView
}
}
}
}
.onAppear {
viewModel.onLogout = onLogout
viewModel.onAppear()
}
.onChange(of: viewModel.isLoggedOut) { _, isLoggedOut in
if isLoggedOut {
onLogout()
}
}
}
// MARK: - UI Components
private func mainContentView(geometry: GeometryProxy) -> some View {
Group {
switch viewModel.selectedTab {
case .feed:
TempFeedListPage()
case .me:
TempMePage()
}
}
}
private var bottomTabView: some View {
HStack(spacing: 0) {
ForEach(MainViewModel.Tab.allCases, id: \.self) { tab in
Button(action: {
viewModel.onTabChanged(tab)
}) {
VStack(spacing: 4) {
Image(systemName: tab.iconName)
.font(.system(size: 24))
.foregroundColor(viewModel.selectedTab == tab ? .white : .white.opacity(0.6))
Text(tab.title)
.font(.system(size: 12))
.foregroundColor(viewModel.selectedTab == tab ? .white : .white.opacity(0.6))
}
}
.frame(maxWidth: .infinity)
.padding(.vertical, 8)
}
}
.background(
Rectangle()
.fill(Color.black.opacity(0.3))
.background(.ultraThinMaterial)
)
}
}
// MARK: - FeedListView ()
struct TempFeedListPage: View {
var body: some View {
VStack {
Text("Feed List")
.font(.title)
.foregroundColor(.white)
Text("This is a simplified FeedListView")
.font(.body)
.foregroundColor(.white.opacity(0.8))
}
}
}
// MARK: - MeView ()
struct TempMePage: View {
var body: some View {
VStack {
Text("Me View")
.font(.title)
.foregroundColor(.white)
Text("This is a simplified MeView")
.font(.body)
.foregroundColor(.white.opacity(0.8))
}
}
}
#Preview {
MainPage(onLogout: {})
}