今天開始,我們要正式進入專案實作階段
實作主題是:飲食記錄 App
第一步,我們先來打造 App 的「首頁」,讓使用者能夠快速瀏覽每日的飲食狀況與營養統計
我們要完成一個可以顯示 每日營養資訊 與 餐點清單 的首頁畫面,整體結構如下:
首先,我們定義一個簡單的資料結構,代表一筆餐點:
struct MealRecord: Identifiable {
let id = UUID()
let name: String
let calories: Int
let category: MealCategory
let date: Date
}
enum MealCategory: String, CaseIterable {
case breakfast = "早餐"
case lunch = "午餐"
case dinner = "晚餐"
case snack = "點心"
}
接著建立 DashboardViewModel
,用來管理今日的餐點資料與營養統計:
import SwiftUI
class MealViewModel: ObservableObject {
@Published var records: [MealRecord] = [
MealRecord(name: "燕麥牛奶", calories: 200, category: .breakfast, date: Date()),
MealRecord(name: "雞胸肉便當", calories: 500, category: .lunch, date: Date()),
MealRecord(name: "沙拉", calories: 300, category: .dinner, date: Date()),
MealRecord(name: "香蕉", calories: 100, category: .snack, date: Date())
]
var totalCalories: Int {
records.reduce(0) { $0 + $1.calories }
}
// 假資料
var protein: Int { 60 }
var carbs: Int { 150 }
var fat: Int { 40 }
}
接下來是主畫面
struct DashboardView: View {
@StateObject private var viewModel = MealViewModel()
var body: some View {
NavigationView {
List {
// 營養統計區塊
Section {
VStack(alignment: .leading, spacing: 8) {
Text("今日總計")
.font(.headline)
Text("卡路里:\(viewModel.totalCalories) kcal")
HStack {
Label("蛋白質:\(viewModel.protein)g", systemImage: "bolt.heart")
Spacer()
Label("碳水:\(viewModel.carbs)g", systemImage: "leaf")
Spacer()
Label("脂肪:\(viewModel.fat)g", systemImage: "drop")
}
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding(.vertical, 8)
}
// 餐別清單
ForEach(MealCategory.allCases, id: \.self) { category in
Section(header: Text(category.rawValue)) {
let meals = viewModel.records.filter { $0.category == category}
if meals.isEmpty {
Text("尚未新增餐點")
.foregroundColor(.gray)
} else {
ForEach(meals) { meal in
HStack {
Text(meal.name)
Spacer()
Text("\(meal.calories) kcal")
.foregroundColor(.secondary)
}
}
}
}
}
// 新增記錄按鈕
Section {
Button(action: {
print("新增記錄")
}) {
Label("新增記錄", systemImage: "plus.circle.fill")
.font(.headline)
.foregroundColor(.blue)
}
.frame(maxWidth: .infinity, alignment: .center)
}
}
.navigationTitle("今日飲食")
}
}
}
#Preview {
DashboardView()
}
完成後的畫面類似下圖:
明天我們將進一步開發「新增記錄」頁面,讓使用者能夠輸入餐點名稱與卡路里,並即時更新首頁統計結果。