refactor: 重命名项目名称从"体己"到"康康" 将整个项目的目录结构从"体己"重命名为"康康",包括所有源代码文件、 资源文件、测试文件以及Xcode项目配置文件。此更改涉及项目中所有的 文件路径和应用入口点(App/TijiApp.swift → App/KangkangApp.swift)。 ```
152 lines
4.4 KiB
Swift
152 lines
4.4 KiB
Swift
import SwiftUI
|
|
|
|
enum TjTab: String, Hashable, CaseIterable {
|
|
case home, trend, me
|
|
var label: String {
|
|
switch self {
|
|
case .home: return "首页"
|
|
case .trend: return "趋势"
|
|
case .me: return "我的"
|
|
}
|
|
}
|
|
var icon: String {
|
|
switch self {
|
|
case .home: return "house"
|
|
case .trend: return "chart.line.uptrend.xyaxis"
|
|
case .me: return "person.circle"
|
|
}
|
|
}
|
|
}
|
|
|
|
enum ActiveFlow: Identifiable {
|
|
case quick, archive
|
|
var id: String { String(describing: self) }
|
|
}
|
|
|
|
struct RootView: View {
|
|
@State private var tab: TjTab = .home
|
|
@State private var showRecordSheet = false
|
|
@State private var activeFlow: ActiveFlow?
|
|
|
|
var body: some View {
|
|
VStack(spacing: 0) {
|
|
Group {
|
|
switch tab {
|
|
case .home: HomeView(onTapArchive: {})
|
|
case .trend: TrendsView()
|
|
case .me: MeView()
|
|
}
|
|
}
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
|
|
TabBar(active: tab,
|
|
onTap: { tab = $0 },
|
|
onTapRecord: { showRecordSheet = true })
|
|
}
|
|
.background(Tj.Palette.sand.ignoresSafeArea())
|
|
.sheet(isPresented: $showRecordSheet) {
|
|
RecordSheet { kind in
|
|
showRecordSheet = false
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
|
switch kind {
|
|
case .quick: activeFlow = .quick
|
|
case .archive: activeFlow = .archive
|
|
case .diary: break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#if os(iOS)
|
|
.fullScreenCover(item: $activeFlow) { flow in
|
|
switch flow {
|
|
case .quick:
|
|
QuickCaptureFlow(onClose: { activeFlow = nil })
|
|
case .archive:
|
|
ArchiveFlow(onClose: { activeFlow = nil })
|
|
}
|
|
}
|
|
#else
|
|
.sheet(item: $activeFlow) { flow in
|
|
switch flow {
|
|
case .quick:
|
|
QuickCaptureFlow(onClose: { activeFlow = nil })
|
|
case .archive:
|
|
ArchiveFlow(onClose: { activeFlow = nil })
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
private struct TabBar: View {
|
|
let active: TjTab
|
|
let onTap: (TjTab) -> Void
|
|
let onTapRecord: () -> Void
|
|
|
|
var body: some View {
|
|
HStack(spacing: 0) {
|
|
tabItem(.home)
|
|
Color.clear.frame(width: 60, height: 1)
|
|
tabItem(.trend)
|
|
tabItem(.me)
|
|
}
|
|
.padding(.horizontal, 12)
|
|
.padding(.top, 10)
|
|
.padding(.bottom, 4)
|
|
.background(
|
|
Tj.Palette.paper
|
|
.overlay(alignment: .top) {
|
|
Rectangle()
|
|
.fill(Tj.Palette.lineSoft)
|
|
.frame(height: 1)
|
|
}
|
|
)
|
|
.overlay(alignment: .top) {
|
|
recordButton.offset(y: -22)
|
|
}
|
|
}
|
|
|
|
private func tabItem(_ t: TjTab) -> some View {
|
|
Button { onTap(t) } label: {
|
|
VStack(spacing: 4) {
|
|
Image(systemName: t.icon)
|
|
.font(.system(size: 20, weight: .regular))
|
|
.frame(width: 26, height: 26)
|
|
Text(t.label)
|
|
.font(.system(size: 11))
|
|
}
|
|
.foregroundStyle(active == t ? Tj.Palette.ink : Tj.Palette.text3)
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.vertical, 4)
|
|
.contentShape(Rectangle())
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
|
|
private var recordButton: some View {
|
|
Button(action: onTapRecord) {
|
|
VStack(spacing: 4) {
|
|
ZStack {
|
|
Circle()
|
|
.fill(Tj.Palette.ink)
|
|
.shadow(color: Color(red: 0.157, green: 0.216, blue: 0.176).opacity(0.25),
|
|
radius: 12, x: 0, y: 4)
|
|
Image(systemName: "plus")
|
|
.font(.system(size: 20, weight: .semibold))
|
|
.foregroundStyle(Tj.Palette.paper)
|
|
}
|
|
.frame(width: 52, height: 52)
|
|
|
|
Text("记录")
|
|
.font(.system(size: 11))
|
|
.foregroundStyle(Tj.Palette.ink)
|
|
}
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
RootView()
|
|
}
|