Xcode Beta 5下SwiftUI的@FetchRequest动态修改与排序切换方案问询
这个问题我之前也碰到过!核心原因是你当前的@FetchRequest在MainView初始化时只调用了一次Manager.shared.fetchRequest(),之后不管reverse怎么变化,这个初始的请求都不会被重新生成,所以列表的排序自然不会跟着更新。
下面是调整后的可行方案,能让排序规则随用户操作动态变化:
修改后的MainView代码
struct MainView: some View { @ObservedObject var manager: Manager // 先初始化一个空的sortDescriptors数组,后续在init中设置初始值 @FetchRequest(sortDescriptors: []) var ts: FetchedResults<T> init(manager: Manager) { self.manager = manager // 根据manager初始的reverse值设置排序规则 let initialSort = NSSortDescriptor(key: "name", ascending: !manager.reverse) _ts = FetchRequest(sortDescriptors: [initialSort]) } var body: some View { NavigationView { List(ts, id: \.self) { t in Text(t.name) } } .navigationBarItems(trailing: Button(action: { self.manager.reverse.toggle() }) { Text("Reverse") }) // 监听reverse属性的变化,实时更新排序规则 .onReceive(manager.$reverse) { newReverse in _ts.sortDescriptors = [NSSortDescriptor(key: "name", ascending: !newReverse)] } } }
简化后的Manager类
你可以去掉fetchRequest方法里多余的参数,因为它直接使用自身的reverse属性:
final class Manager: ObservableObject { @Published var reverse: Bool = false public static let shared = Manager() func fetchRequest() -> NSFetchRequest<T> { let request: NSFetchRequest<T> = T.fetchRequest() request.sortDescriptors = [ NSSortDescriptor( key: "name", ascending: !self.reverse ) ] return request } }
为什么这样有效?
- 初始排序设置:在MainView的初始化方法中,我们根据manager当前的
reverse值设置了初始的排序规则,确保页面加载时数据就是正确排序的。 - 动态更新排序:通过
onReceive(manager.$reverse)监听reverse属性的变化,每当用户点击"Reverse"按钮切换排序方向时,我们直接更新_ts.sortDescriptors——这个操作会触发@FetchRequest重新执行Core Data查询,获取按新规则排序的数据,从而自动更新列表展示。
内容的提问来源于stack exchange,提问作者Hugo Lundin
相关产品推荐
相关产品推荐

