你好。我叫 Tomita,是一名负责天气和灾害服务的 iOS 应用工程师。
在前几天举行的 try!Swift Tokyo 2024 的 LINE Yahoo 企业展位上,我们举办了代码审查挑战赛。 代码审查挑战赛是一项公共代码审查,旨在将坏代码变成好代码。我们在本次活动中采取了与以往活动相同的举措,目的是让参与者对技术产生兴趣,并帮助员工通过外部各方的评论进行学习。
在这篇文章中,我将解释这次提出的 Code Review Challenge 的第二个问题。
问题代码
import SwiftUI
import SwiftData
struct ContentView: View {
// Initialized ModelContainer will be passed from the parent view.
@Environment(.modelContext) private var modelContext
// Todo class is decleared with @Model annotation on another file.
@Query private var todos: [Todo]
@State private var showingAddItemAlert = false
@State private var newTodo = ""
var body: some View {
NavigationView {
List {
ForEach(Array(todos.filter { !$0.isDone }.enumerated()), id: .offset) { index, todo in
Button(todo.title) {
todos[index].isDone.toggle()
}
}
.onDelete(perform: deleteItems)
}
.toolbar {
Button(action: {
showingAddItemAlert = true
}, label: {
Image(systemName: "plus")
})
}
.overlay {
if todos.count == 0 {
ContentUnavailableView(
"All Done",
systemImage: "checkmark",
description: Text("You've completed all your tasks. Congratulations!")
)
}
}
.alert("Add New Todo", isPresented: $showingAddItemAlert) {
TextField("New Todo", text: $newTodo)
Button("Add", action: addItem)
.disabled(newTodo.isEmpty)
Button("Cancel", role: .cancel, action: {})
}
}
}
private func addItem() {
let newItem = Todo(title: newTodo)
modelContext.insert(newItem)
newTodo = ""
}
private func deleteItems(offsets: IndexSet) {
for index in offsets {
modelContext.delete(todos[index])
}
}
}
这是使用 SwiftData 的 TODO 应用程序的代码。其中包括10多个改进,但这次我主要介绍以下两点。
- 关于从 SwiftData 获取的数据的处理
- 关于使用警报添加 TODO
关于从 SwiftData 获取的数据的处理
上面的代码中,显示List时todos
正在过滤。因此,显示上没有问题,但是在删除或编辑时(本例中将任务的isDone设置为true),会操作移动索引的元素。这个问题可以通过搜索过滤后的TODO索引来解决,但搜索会增加处理时间,因此不是最佳解决方案。这个问题可以通过使用SwiftData提供的API来解决。实际修改后的代码如下。
// 前略
@Query(filter: #Predicate { !$0.isDone }) private var todos: [Todo]
@State private var showingAddItemAlert = false
var body: some View {
NavigationView {
List {
ForEach(todos) { todo in
Button(todo.title) {
todo.isDone.toggle()
}
}
.onDelete(perform: deleteItems)
}
// 後略
检索 Swift Data 中存储的内容时@Query
使用 检索数据,但可以在此处添加过滤和排序等选项。这允许您在检索元素时对其进行过滤。您还可以在更改元素时进行过滤。
1713268110
#代码审查挑战解释第二个问题SwiftUI #和 #SwiftData
2024-04-16 02:00:00