Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第 14 章:构建一个小型应用

第 14 章:构建一个小型应用

待办事项列表 (ToDo List)

项目概述

在本章中,我们将使用 SwiftData 构建一个完整的待办事项列表应用。该应用将涵盖以下核心功能:

  • 创建、读取、更新和删除待办事项
  • 标记任务完成状态
  • 按日期或优先级排序任务
  • 数据持久化与自动同步

1. 数据模型设计

import SwiftData

@Model
final class TodoItem {
    var title: String
    var isCompleted: Bool
    var dueDate: Date?
    var priority: Priority
    
    enum Priority: Int, Codable, CaseIterable {
        case low = 0, medium, high
    }
    
    init(title: String, isCompleted: Bool = false, dueDate: Date? = nil, priority: Priority = .medium) {
        self.title = title
        self.isCompleted = isCompleted
        self.dueDate = dueDate
        self.priority = priority
    }
}

2. 设置 ModelContainer

在应用的入口点初始化容器:

import SwiftUI

@main
struct TodoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(for: TodoItem.self)
    }
}

3. 核心功能实现

添加新任务

struct AddTodoView: View {
    @Environment(\.modelContext) private var context
    @Environment(\.dismiss) private var dismiss
    
    @State private var title = ""
    @State private var dueDate = Date()
    @State private var priority = TodoItem.Priority.medium
    
    var body: some View {
        Form {
            TextField("任务标题", text: $title)
            DatePicker("截止日期", selection: $dueDate)
            Picker("优先级", selection: $priority) {
                ForEach(TodoItem.Priority.allCases, id: \.self) {
                    Text($0.description)
                }
            }
            Button("添加") {
                let newItem = TodoItem(
                    title: title,
                    dueDate: dueDate,
                    priority: priority
                )
                context.insert(newItem)
                dismiss()
            }
        }
    }
}

任务列表视图

struct TodoListView: View {
    @Query(sort: \TodoItem.dueDate) private var items: [TodoItem]
    
    var body: some View {
        List {
            ForEach(items) { item in
                TodoItemRow(item: item)
            }
            .onDelete(perform: deleteItems)
        }
        .toolbar {
            Button("添加", systemImage: "plus") {
                // 显示添加视图
            }
        }
    }
    
    private func deleteItems(_ indexSet: IndexSet) {
        for index in indexSet {
            let item = items[index]
            context.delete(item)
        }
    }
}

任务状态切换

struct TodoItemRow: View {
    @Bindable var item: TodoItem
    
    var body: some View {
        HStack {
            Image(systemName: item.isCompleted ? "checkmark.circle.fill" : "circle")
                .onTapGesture {
                    item.isCompleted.toggle()
                }
            
            VStack(alignment: .leading) {
                Text(item.title)
                    .strikethrough(item.isCompleted)
                
                if let dueDate = item.dueDate {
                    Text(dueDate.formatted())
                        .font(.caption)
                }
            }
            
            Spacer()
            
            PriorityBadge(priority: item.priority)
        }
    }
}

4. 高级功能实现

筛选与排序

enum TodoFilter: String, CaseIterable {
    case all, completed, pending
}

struct TodoListView: View {
    @State private var selectedFilter: TodoFilter = .all
    @State private var sortOrder = [SortDescriptor(\TodoItem.dueDate)]
    
    var body: some View {
        let predicate = buildPredicate()
        @Query(filter: predicate, sort: sortOrder) var filteredItems: [TodoItem]
        
        // 列表实现...
        
        Picker("筛选", selection: $selectedFilter) {
            ForEach(TodoFilter.allCases, id: \.self) {
                Text($0.rawValue)
            }
        }
        .pickerStyle(.segmented)
    }
    
    private func buildPredicate() -> Predicate<TodoItem> {
        switch selectedFilter {
        case .all:
            return #Predicate<TodoItem> { _ in true }
        case .completed:
            return #Predicate<TodoItem> { $0.isCompleted }
        case .pending:
            return #Predicate<TodoItem> { !$0.isCompleted }
        }
    }
}

5. 数据预览与测试

在 Xcode 预览中提供测试数据:

#Preview {
    let config = ModelConfiguration(isStoredInMemoryOnly: true)
    let container = try! ModelContainer(for: TodoItem.self, configurations: config)
    
    // 添加示例数据
    for i in 1..<10 {
        let item = TodoItem(
            title: "任务 \(i)",
            isCompleted: Bool.random(),
            dueDate: Date().addingTimeInterval(Double.random(in: 0...86400*7)),
            priority: TodoItem.Priority.allCases.randomElement()!
        )
        container.mainContext.insert(item)
    }
    
    return NavigationStack {
        TodoListView()
    }
    .modelContainer(container)
}

6. 项目扩展建议

  1. 分类功能:为任务添加分类标签
  2. 提醒通知:使用 NotificationCenter 实现任务提醒
  3. 数据统计:显示任务完成情况的统计图表
  4. iCloud 同步:启用 CloudKit 实现跨设备同步
  5. Widget 支持:在主屏幕显示近期任务

7. 完整项目结构

TodoApp/
├── Models/
│   └── TodoItem.swift
├── Views/
│   ├── TodoListView.swift
│   ├── AddTodoView.swift
│   ├── TodoItemRow.swift
│   └── PriorityBadge.swift
├── Utilities/
│   └── PredicateBuilder.swift
└── TodoApp.swift

通过这个项目,您已经掌握了使用 SwiftData 构建完整应用的核心流程。接下来可以尝试实现笔记应用或联系人管理来巩固所学知识。

Last Updated:: 5/30/25, 5:48 PM