当然,我们可以纯粹使用Swift和UIKit来创建一个简单的To-do List应用程序。这里是一个简单的包含UI和逻辑的示例。
首先,你需要在Xcode中创建一个新的项目,选择App并命名为TodoList_SwiftUIKit。
以下是一些关键代码片段:
1.定义ToDo的数据模型
struct ToDo {
var title: String
var isComplete: Bool
}
2.创建ToDo列表视图控制器(TableViewController)
import UIKit
class ToDoListViewController: UITableViewController {
// 初始化一个空的待办事项数组
var toDoItems: [ToDo] = []
override func viewDidLoad() {
super.viewDidLoad()
// 设置标题
self.title = "To-Do List"
// 添加导航按钮
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addTodo))
}
// 添加待办事项的操作
@objc private func addTodo() {
// 这是一个弹窗视图,用于获取用户输入的待办事项名称,然后将其添加到待办事项数组中
let alertController = UIAlertController(title: "Add Todo", message: nil, preferredStyle: .alert)
alertController.addTextField()
let addAction = UIAlertAction(title: "Add", style: .default) { _ in
guard
let text = alertController.textFields?.first?.text,
!text.isEmpty
else { return }
self.toDoItems.append(ToDo(title: text, isComplete: false))
self.tableView.reloadData()
}
alertController.addAction(addAction)
present(alertController, animated: true)
}
}
这段代码是在使用iOS开发中的UIAlertController和UIAlertAction来创建一个弹出对话框,并添加一个名为"Add"的操作按钮。
首先,创建了一个带有标题“Add”和默认样式(.default)的UI警告操作。该操作会在用户点击“Add”按钮时触发。
当用户点击“Add”按钮时,代码块 { _ in ... } 会执行。此处的 _ in 表示这个闭包忽略了传入的参数(在这种情况下,该参数将是触发该操作的UIAlertAction实例)。
接下来是一个 guard 语句,它用于提前退出函数或闭包,避免进一步的嵌套。let text = alertController.textFields?.first?.text 尝试从弹出框的第一个文本字段获取文本。如果无法获取文本或文本为空( !text.isEmpty 为假),则 guard 语句就会触发,立即退出闭包,剩下的代码不会执行。
如果能够成功获取非空的文本,那么 self.toDoItems.append(ToDo(title: text, isComplete: false)) 就会被执行,它创建一个新的 ToDo 对象并将其添加到 toDoItems 数组中。每个 ToDo 对象都有一个标题(用户输入的文本)和一个标记是否完成的布尔值(在这种情况下始终为 false)。
最后,self.tableView.reloadData() 被调用以刷新表视图,显示新添加的待办事项。
总的来说,这段代码主要用于创建一个弹出对话框,允许用户输入新的待办事项,然后将新的待办事项添加到列表中,并刷新表格以显示新的待办事项。
3.实现UITableViewDataSource方法:
extension ToDoListViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return toDoItems.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
let item = toDoItems[indexPath.row]
cell.textLabel?.text = item.title
cell.accessoryType = item.isComplete ? .checkmark : .none
return cell
}
}
4.实现UITableViewDelegate方法:
extension ToDoListViewController {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// 更新待办事项的完成状态
toDoItems[indexPath.row].isComplete.toggle()
tableView.reloadRows(at: [indexPath], with: .automatic)
}
}
以上代码就已经实现了一个基本的ToDo列表。但是这个应用还很简单,你可能希望添加如下功能:
- 删除待办事项
- 编辑待办事项
- 持久化存储待办事项
- 分类待办事项
以上提供的代码仅供参考,具体实现会根据你对应用的需求不同而有所差异。
以下是你可以添加到在上面的基本ToDo列表中来实现删除,编辑,持久化存储和分类待办事项功能。我们会使用UserDefaults进行简单的持久化存储,实际项目开发中可能会需要更复杂的数据库系统。
1.删除待办事项
在UITableViewDelegate扩展中添加以下方法:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
toDoItems.remove(at: indexPath.row)
// 持久化存储删除操作
saveData()
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
2.编辑待办事项
可以在didSelectRowAt方法中添加代码以处理编辑动作:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let alertController = UIAlertController(title: "Edit Todo", message: nil, preferredStyle: .alert)
alertController.addTextField { textField in
textField.text = self.toDoItems[indexPath.row].title
}
let editAction = UIAlertAction(title: "Edit", style: .default) { _ in
guard
let text = alertController.textFields?.first?.text,
!text.isEmpty
else { return }
self.toDoItems[indexPath.row].title = text
// 持久化存储编辑操作
self.saveData()
tableView.reloadRows(at: [indexPath], with: .automatic)
}
alertController.addAction(editAction)
present(alertController, animated: true)
}
3.持久化存储
可以使用UserDefaults存储待办事项。由于UserDefaults无法直接存储自定义类型,我们需要将待办事项转换为可以被UserDefaults存储的类型。同时,我们也需要在应用启动时从UserDefaults载入数据。
在ToDoListViewController类中添加以下方法:
private func saveData() {
let data = try? JSONEncoder().encode(toDoItems)
UserDefaults.standard.set(data, forKey: "toDoItems")
}
private func loadData() {
guard
let data = UserDefaults.standard.data(forKey: "toDoItems"),
let items = try? JSONDecoder().decode([ToDo].self, from: data)
else { return }
toDoItems = items
}
然后在viewDidLoad方法中调用loadData()以载入数据,并在addTodo和tableView(_:commit:forRowAt:)方法中调用saveData()以保存数据。
4.分类待办事项
这个需求较为复杂,可能需要重新设计数据模型和UI。例如,可以将ToDo结构体修改为:
struct ToDo {
var title: String
var isComplete: Bool
var category: String
}
并在addTodo方法中添加代码以获取用户输入的分类。
同时,你可能需要一个新的TableView或者CollectionView来显示不同分类的待办事项,具体实现会根据你对UI和交互设计的要求有所不同。
以上代码仅供参考,完整的实现需要你自己根据实际需求进行适当的修改和扩展。
要实现分类待办事项,我们需要增加一个新的表格视图控制器(CategoryTableViewController)来展示所有的类别。然后在每个类别内部,都可以跳转到相应的待办列表。
首先,我们将ToDo结构体修改为:
struct ToDo {
var title: String
var isComplete: Bool
var category: String
}
然后在ToDoListViewController中添加以下代码,用于初始化显示特定类别的待办事项:
var categoryName: String?
override func viewDidLoad() {
super.viewDidLoad()
// 设置标题为当前类别名称
self.title = categoryName
// 其他代码...
}
// 修改数据源方法,只显示当前类别的待办事项
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return toDoItems.filter { $0.category == categoryName }.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
let item = toDoItems.filter { $0.category == categoryName }[indexPath.row]
cell.textLabel?.text = item.title
cell.accessoryType = item.isComplete ? .checkmark : .none
return cell
}
接着创建一个新的CategoryTableViewController,用于显示所有的待办事项类别:
import UIKit
class CategoryTableViewController: UITableViewController {
// 存储所有的类别名称
var categories: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Categories"
// 添加导航按钮
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addCategory))
}
@objc private func addCategory() {
// 与添加待办事项类似,弹出对话框让用户输入新的类别名称,并存储起来
}
}
extension CategoryTableViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = categories[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// 当用户选择一个类别时,进入该类别的待办事项列表
let todoListViewController = ToDoListViewController()
todoListViewController.categoryName = categories[indexPath.row]
navigationController?.pushViewController(todoListViewController, animated: true)
}
}
请注意这是一个基本的实现,你可能需要根据具体需求进行修改和扩展,例如添加删除类别功能,或者使用更复杂的数据持久化方案以处理大量数据。
在CategoryTableViewController中实现添加和删除类别功能,具体步骤如下:
1.添加类别
@objc private func addCategory() {
let alertController = UIAlertController(title: "Add Category", message: nil, preferredStyle: .alert)
alertController.addTextField()
let addAction = UIAlertAction(title: "Add", style: .default) { _ in
guard
let text = alertController.textFields?.first?.text,
!text.isEmpty
else { return }
self.categories.append(text)
// 持久化存储添加操作
self.saveData()
self.tableView.reloadData()
}
alertController.addAction(addAction)
present(alertController, animated: true)
}
2.删除类别
可以使用.delete编辑风格在滑动单元格时显示删除按钮。在UITableViewDelegate扩展中添加以下代码:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// 删除类别前需检查是否存在属于该类别的待办事项
let category = categories[indexPath.row]
if !toDoItems.contains(where: { $0.category == category }) {
categories.remove(at: indexPath.row)
// 持久化存储删除操作
saveData()
tableView.deleteRows(at: [indexPath], with: .fade)
} else {
let alert = UIAlertController(title: "Warning", message: "This category contains to-do items. Please delete them first.", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default)
alert.addAction(okAction)
present(alert, animated: true)
}
}
}
3.持久化存储
使用UserDefaults存储类别列表。同样由于UserDefaults无法直接存储自定义类型,我们需要将待办事项转换为可以被UserDefaults存储的类型。同时,我们也需要在应用启动时从UserDefaults载入数据。
在CategoryTableViewController类中添加以下方法:
private func saveData() {
UserDefaults.standard.set(categories, forKey: "categories")
}
private func loadData() {
if let items = UserDefaults.standard.array(forKey: "categories") as? [String] {
categories = items
}
}
然后在viewDidLoad方法中调用loadData()以载入数据,并在addCategory和tableView(_:commit:forRowAt:)方法中调用saveData()以保存数据。
以上就是添加和删除类别功能的基本实现,你可能还需要根据具体需求进行修改和扩展。