iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
Mobile Development

SwiftUI快速入門30天系列 第 29

Day29 - SwiftUI綜合練習ToDo List

  • 分享至 

  • xImage
  •  

這是一個包含 DatePickerToggle (打勾的功能)、AlertView 的簡單 ToDo List SwiftUI 範例。此範例展示如何創建待辦事項列表,每個項目都有打勾的功能,以及點選完成後變色。並且會使用 DatePicker 來選擇日期與時間。

以下是完整的 SwiftUI 代碼:

import SwiftUI

struct TodoItem: Identifiable {
    let id = UUID()
    var task: String
    var isCompleted: Bool = false
    var dueDate: Date = Date()
}

struct ContentView: View {
    @State private var todoItems: [TodoItem] = []
    @State private var newTask: String = ""
    @State private var showAlert = false
    @State private var dueDate = Date()
    
    var body: some View {
        NavigationView {
            VStack {
                HStack {
                    TextField("Enter new task", text: $newTask)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding(.horizontal)
                    
                    DatePicker("", selection: $dueDate, displayedComponents: [.date, .hourAndMinute])
                        .labelsHidden()
                        .padding(.trailing)
                    
                    Button(action: {
                        addNewTask()
                    }) {
                        Image(systemName: "plus.circle.fill")
                            .font(.largeTitle)
                            .foregroundColor(.blue)
                    }
                }
                .padding()
                
                List {
                    ForEach(todoItems) { item in
                        HStack {
                            Toggle(isOn: Binding(
                                get: { item.isCompleted },
                                set: { newValue in
                                    markCompleted(item: item, isCompleted: newValue)
                                }
                            )) {
                                Text(item.task)
                                    .strikethrough(item.isCompleted)
                                    .foregroundColor(item.isCompleted ? .gray : .primary)
                            }
                            Spacer()
                            Text("\(item.dueDate, style: .date) \(item.dueDate, style: .time)")
                                .font(.caption)
                                .foregroundColor(.secondary)
                        }
                    }
                    .onDelete(perform: deleteTask)
                }
            }
            .navigationTitle("ToDo List")
            .navigationBarItems(trailing: EditButton())
            .alert(isPresented: $showAlert) {
                Alert(
                    title: Text("Error"),
                    message: Text("Task cannot be empty."),
                    dismissButton: .default(Text("OK"))
                )
            }
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
    
    private func addNewTask() {
        guard !newTask.isEmpty else {
            showAlert = true
            return
        }
        
        let newItem = TodoItem(task: newTask, dueDate: dueDate)
        todoItems.append(newItem)
        newTask = ""
        dueDate = Date()
    }
    
    private func markCompleted(item: TodoItem, isCompleted: Bool) {
        if let index = todoItems.firstIndex(where: { $0.id == item.id }) {
            todoItems[index].isCompleted = isCompleted
        }
    }
    
    private func deleteTask(at offsets: IndexSet) {
        todoItems.remove(atOffsets: offsets)
    }
}

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

代碼解釋:

  1. TodoItem 模型:每個待辦事項由 task (任務名稱)、isCompleted (是否完成) 和 dueDate (到期日期) 組成。UUID 用於唯一標識每個項目。

  2. ContentView 結構

    • 使用 @State 管理待辦清單 (todoItems)、新任務 (newTask) 和其他狀態變數。
    • TextField:用於輸入新任務。
    • DatePicker:允許用戶選擇日期和時間。
    • Button:點擊加號按鈕後,調用 addNewTask() 方法將新任務加入清單。
    • List:顯示所有待辦事項,並為每個項目提供一個 Toggle,以允許打勾標記完成。標記完成的項目會顯示刪除線並變灰色。
    • Alert:當試圖添加空任務時,彈出錯誤提示。
  3. 功能實現

    • addNewTask():確保新任務不為空,否則彈出警告提示。
    • markCompleted():用來標記任務是否完成,並更新界面顯示。
    • deleteTask(at:):允許用戶滑動刪除任務。

預覽:

  • 使用 ContentView_Previews 提供 Xcode 的 SwiftUI 預覽功能,方便開發時即時查看效果。

這樣的應用已包含最基本的待辦事項功能,並且符合 SwiftUI 的最佳實踐,方便未來擴展和維護。


上一篇
Day28 - 介紹常用的SwiftUI Warp @開頭的包裝屬性
下一篇
Day 30 - 終於完賽了心得與 SwiftUI 總結
系列文
SwiftUI快速入門30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言