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
  • 第二部分:MVVM 在 SwiftUI 中的实现

第二部分:MVVM 在 SwiftUI 中的实现

第4章:设计 View 层

案例:基于 Todo 模型的列表界面

1. 需求分析

我们需要实现一个简单的 Todo 列表界面,包含以下功能:

  • 显示 Todo 项的列表(标题、完成状态)
  • 支持新增 Todo 项
  • 支持标记 Todo 项为完成/未完成
  • 支持删除 Todo 项

2. 视图结构设计

struct TodoListView: View {
    @ObservedObject var viewModel: TodoListViewModel
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(viewModel.todos) { todo in
                    TodoRowView(todo: todo)
                        .onTapGesture {
                            viewModel.toggleCompletion(for: todo.id)
                        }
                }
                .onDelete(perform: viewModel.deleteTodo)
            }
            .navigationTitle("Todo List")
            .toolbar {
                Button(action: viewModel.addNewTodo) {
                    Image(systemName: "plus")
                }
            }
        }
    }
}

struct TodoRowView: View {
    let todo: Todo
    
    var body: some View {
        HStack {
            Image(systemName: todo.isCompleted ? "checkmark.circle.fill" : "circle")
                .foregroundColor(todo.isCompleted ? .green : .gray)
            Text(todo.title)
            Spacer()
        }
    }
}

3. 状态管理实现

class TodoListViewModel: ObservableObject {
    @Published var todos: [Todo] = []
    
    func addNewTodo() {
        let newTodo = Todo(
            id: UUID(),
            title: "New Task \(todos.count + 1)",
            isCompleted: false
        )
        todos.append(newTodo)
    }
    
    func toggleCompletion(for id: UUID) {
        if let index = todos.firstIndex(where: { $0.id == id }) {
            todos[index].isCompleted.toggle()
        }
    }
    
    func deleteTodo(at offsets: IndexSet) {
        todos.remove(atOffsets: offsets)
    }
}

4. 数据模型定义

struct Todo: Identifiable {
    let id: UUID
    var title: String
    var isCompleted: Bool
}

5. 预览实现

struct TodoListView_Previews: PreviewProvider {
    static var previews: some View {
        let viewModel = TodoListViewModel()
        viewModel.todos = [
            Todo(id: UUID(), title: "Buy groceries", isCompleted: false),
            Todo(id: UUID(), title: "Finish report", isCompleted: true)
        ]
        return TodoListView(viewModel: viewModel)
    }
}

6. 关键实现说明

  1. 数据流:ViewModel 通过 @Published 属性包装器发布数据变更,View 通过 @ObservedObject 监听变化
  2. 交互处理:用户操作通过 ViewModel 方法处理,保持 View 的简洁性
  3. 组件拆分:将列表项拆分为独立的 TodoRowView 组件,提高可维护性
  4. 状态管理:使用 SwiftUI 原生的状态管理方案,避免引入复杂的状态管理库

7. 扩展思考

  • 如何添加编辑功能?
  • 如何实现分类筛选?
  • 如何添加本地持久化存储?
Last Updated:: 4/25/25, 8:11 PM