温馨提示:本文最后更新于
2025-01-20 14:12:40
,某些文章具有时效性,若有错误或已失效,请在下方留言。要实现动态排序,您需要将@Query
属性移至 SwiftUI 层次结构中的视图中 – 您需要将其放入子视图中,在其中可以使用依赖项注入提供排序值。
这意味着创建一个新的 SwiftUI,它使用@Query
来显示您正在使用的 SwiftData 对象,然后将其嵌入到父视图中,该父视图为用户提供一些 UI 以选择排序顺序或过滤器。
例如,如果我们使用User模型,那么我们可能会创建一个如下所示的UserListingView
:
import SwiftData
import SwiftUI
struct UserListingView: View {
@Query var users: [User]
@Environment(\.modelContext) var modelContext
var body: some View {
List {
ForEach(users) { user in
NavigationLink(value: user) {
Text("\(user.name) is \(user.age) years old")
}
}
.onDelete(perform: deleteUser)
}
}
func deleteUser(_ indexSet: IndexSet) {
for item in indexSet {
let object = users[item]
modelContext.delete(object)
}
}
}
然后回到ContentView
中,我们可以在列表中创建它,如下所示:
NavigationStack {
UserListingView()
}
此更改实际上并不处理排序 – 这只是使排序成为可能所需的设置。但是,因为我们现在有一个子视图,所以我们可以将值发送到那里来控制@Query
属性包装器。
这总共需要四个步骤:
- 告诉
UserListingView
它需要以某种排序顺序创建。 - 当程序运行时,创建一些存储来保存当前活动的排序顺序。
- 创建
UserListingView
时将该值传递给它。 - 创建一些 UI 来根据用户的设置调整排序顺序。
第1步
需要调整UserListingView
中的初始化程序,以便它使用从父视图传入的排序描述符来更改查询。这需要更改查询对象本身而不是其中的数组,因此我们需要像这样访问带下划线的属性名称:
init(sort: SortDescriptor<User>) {
_users = Query(sort: [sort])
}
第2步
然后在ContentView中,我们添加一个属性来存储当前的排序顺序,并使用合理的默认值:
@State private var sortOrder = SortDescriptor(\User.name)
第3步
然后,我们可以将其传递到嵌入的UserListingView中,如下所示:
UserListingView(sort: sortOrder)
第4步
最后,我们需要ContentView
中的一些 UI 来向用户提供各种排序选项,然后根据需要调整排序顺序。例如,我们可以将其放入工具栏中:
Menu("Sort") {
Picker("Sort", selection: $sortOrder) {
Text("Name")
.tag(SortDescriptor(\User.name))
Text("Age")
.tag(SortDescriptor(\User.age, order: .reverse))
Text("City")
.tag(SortDescriptor(\User.city))
}
.pickerStyle(.inline)
}
这里发生的情况是,我们将排序选择从UserListingView
上移了一级,这意味着我们现在可以动态控制它。每当排序顺序发生变化时,SwiftUI 都会自动重新创建UserListingView
,这反过来又会重新创建查询。
© 版权声明
THE END
暂无评论内容