2. 使用SwiftUI构建基础界面

任务说明

本案例将使用SwiftUI构建一个“待办事项列表”基础界面,包含:列表展示、添加新事项、删除事项三个核心交互。完成本案例后,你将得到一个可在iOS模拟器或真机上运行的完整应用界面,并理解SwiftUI声明式UI的基本工作方式。

界面结构设计

待办事项 编辑 ✓ 完成课程作业 删除 购买 groceries 删除 预约医生 删除 输入新事项... 添加 NavigationView 导航栏 List 动态列表 TextField + Button 添加区域

项目创建与配置

使用Xcode 15或更高版本,创建新项目:选择 iOS App 模板,产品名称设为 TodoList,Interface 选择 SwiftUI,Language 选择 Swift。无需勾选Core Data等附加选项。

完整代码实现

将 ContentView.swift 的全部内容替换为以下代码:

import SwiftUI

// 待办事项数据模型
struct TodoItem: Identifiable {
    let id = UUID()
    var title: String
    var isDone: Bool = false
}

// 主视图
struct ContentView: View {
    @State private var todos: [TodoItem] = [
        TodoItem(title: "完成课程作业", isDone: true),
        TodoItem(title: "购买 groceries"),
        TodoItem(title: "预约医生")
    ]
    @State private var newTodoTitle = ""
    
    var body: some View {
        NavigationView {
            VStack {
                // 添加区域
                HStack {
                    TextField("输入新事项...", text: $newTodoTitle)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding(.horizontal)
                    
                    Button(action: addTodo) {
                        Text("添加")
                            .fontWeight(.semibold)
                            .padding(.horizontal, 16)
                            .padding(.vertical, 8)
                            .background(Color.blue)
                            .foregroundColor(.white)
                            .cornerRadius(8)
                    }
                    .disabled(newTodoTitle.trimmingCharacters(in: .whitespaces).isEmpty)
                    .padding(.trailing)
                }
                .padding(.vertical, 8)
                
                // 列表区域
                List {
                    ForEach($todos) { $todo in
                        HStack {
                            Button(action: { todo.isDone.toggle() }) {
                                Image(systemName: todo.isDone ? "checkmark.circle.fill" : "circle")
                                    .foregroundColor(todo.isDone ? .blue : .gray)
                                    .font(.title2)
                            }
                            .buttonStyle(BorderlessButtonStyle())
                            
                            Text(todo.title)
                                .strikethrough(todo.isDone, color: .gray)
                                .foregroundColor(todo.isDone ? .gray : .primary)
                        }
                    }
                    .onDelete(perform: deleteTodo)
                }
                .listStyle(PlainListStyle())
            }
            .navigationTitle("待办事项")
            .navigationBarItems(trailing: EditButton())
        }
    }
    
    // 添加新事项
    private func addTodo() {
        let trimmedTitle = newTodoTitle.trimmingCharacters(in: .whitespaces)
        guard !trimmedTitle.isEmpty else { return }
        todos.append(TodoItem(title: trimmedTitle))
        newTodoTitle = ""
    }
    
    // 删除事项
    private func deleteTodo(at offsets: IndexSet) {
        todos.remove(atOffsets: offsets)
    }
}

// 预览
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

代码结构与核心逻辑

上述代码包含三个关键部分:

  • TodoItem 结构体:遵循 Identifiable 协议,每个事项拥有唯一 id,存储标题和完成状态。
  • @State 属性包装器:todos 数组和 newTodoTitle 字符串被标记为状态变量,当它们变化时SwiftUI自动刷新界面。
  • List + ForEach 组合:通过 $todos 双向绑定实现每行的勾选状态切换;.onDelete 修饰符支持滑动删除;EditButton() 提供编辑模式下的批量删除。

运行与验证

在Xcode中点击运行按钮(⌘R),选择模拟器(如iPhone 15 Pro)。验证步骤如下:

  1. 初始状态检查:列表应显示3条预置事项,其中“完成课程作业”左侧为蓝色勾选圆圈,文字带删除线。
  2. 添加功能验证:在底部输入框输入“写周报”,点击“添加”按钮,新事项应出现在列表末尾,输入框自动清空。
  3. 空输入保护:输入框为空时,“添加”按钮呈灰色不可点击状态。
  4. 勾选切换验证:点击任意事项左侧的圆圈图标,该事项在勾选/未勾选状态间切换,文字删除线同步变化。
  5. 删除功能验证:在列表项上向左滑动,点击红色“删除”按钮,该事项从列表消失;或点击导航栏右侧“编辑”按钮,通过红色减号图标删除。

判定标准:以上5项操作均能正常响应且界面实时更新,无崩溃或卡顿,即视为本案例通过。