gpt4 book ai didi

ios - SwiftUI 中的动态过滤器(谓词)

转载 作者:行者123 更新时间:2023-11-28 23:22:00 25 4
gpt4 key购买 nike

我正在使用 SwiftUI 和 CoreData 为 iOS 编写应用程序。几天来我一直在努力解决一个问题。如何根据用户输入在 SwiftUI 中使用动态变化的谓词制作动态过滤器?

我按照本教程学习了动态过滤器和 CoreData:https://www.hackingwithswift.com/quick-start/ios-swiftui/dynamically-filtering-fetchrequest-with-swiftui

经过一些小改动后,我得到了以下代码。ContentView.swift:

import SwiftUI

struct ContentView: View {

@Environment(\.managedObjectContext) var moc
@State var lastNameFilter = "A"

var body: some View {

VStack {
FilteredList(predicate: lastNameFilter)

Button("Add Examples") {
let taylor = Singer(context: self.moc)
taylor.firstName = "Taylor"
taylor.lastName = "Swift"

let ed = Singer(context: self.moc)
ed.firstName = "Ed"
ed.lastName = "Sheeran"

let adele = Singer(context: self.moc)
adele.firstName = "Adele"
adele.lastName = "Adkins"

try? self.moc.save()
}

Button("Show A") {
self.lastNameFilter = "A"
}

Button("Show S") {
self.lastNameFilter = "S"
}
}

}
}

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

FilteredList.swift:

import CoreData
import SwiftUI

struct FilteredList: View {

var predicate:String
var fetchRequest: FetchRequest<Singer>
var singers: FetchedResults<Singer>{fetchRequest.wrappedValue}

var body: some View {
List(singers, id: \.self) { singer in
Text("\(singer.firstName ?? "Unknown") \(singer.lastName ?? "Unknown")")
}
}

init(predicate: String) {
self.predicate = predicate
self.fetchRequest = FetchRequest<Singer>(entity: Singer.entity(), sortDescriptors: [], predicate: NSPredicate(format: "lastName BEGINSWITH %@", predicate))
}

}

//struct FilteredList_Previews: PreviewProvider {
// static var previews: some View {
// }
//}

我还有 1 个名为 Singer 的实体,这个实体有 2 个属性:firstNamelastName,它们都是字符串。上面的示例在模拟器中似乎运行良好,但在 Xcode 中使用预览时应用程序崩溃。

如有任何帮助,我将不胜感激,例如:

  • 指出要更改我的示例代码的哪一部分以避免在预览中出现错误
  • 在 SwiftUI 中使用动态谓词的另一种方式的简单示例
  • 链接到有关 SwiftUI 中的动态过滤器的教程

最佳答案

  1. 要使 ContentView 的预览正常工作,您应该编写如下内容:
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let taylor = Singer(context: context)
taylor.firstName = "Taylor"
taylor.lastName = "Swift"
let ed = Singer(context: context)
ed.firstName = "Ed"
ed.lastName = "Sheeran"
let adele = Singer(context: context)
adele.firstName = "Adele"
adele.lastName = "Adkins"
return ContentView().environment(\.managedObjectContext, context)
}
  1. 您可以实现更通用的 FilteredList 类型,您只需为列表提供谓词(可选的排序描述符)。示例:
struct FilteredList<T: NSManagedObject, Content: View>: View {
var fetchRequest: FetchRequest<T>
var items: FetchedResults<T> { fetchRequest.wrappedValue }

let content: (T) -> Content

var body: some View {
List(items, id: \.self) { item in
self.content(item)
}
}

init(predicate: NSPredicate?, sortDescriptors: [NSSortDescriptor] = [], @ViewBuilder content: @escaping (T) -> Content) {
fetchRequest = FetchRequest<T>(entity: T.entity(), sortDescriptors: sortDescriptors, predicate: predicate)
self.content = content
}
}

将这个新的 FilteredList 类型与 @State private var predicate: NSPredicate? 一起使用,而不是 @State var lastNameFilter = "A"。当需要新的过滤时,只需将这个私有(private)的 @State 属性设置为新的谓词,列表就会相应地更新。

具体用法是:

FilteredList(predicate: predicate) { (singer: Singer) in
Text("\(singer.firstName ?? "") \(singer.lastName ?? "")")
}

过滤列表的预览:

static var previews: some View {
FilteredList(predicate: nil) { (singer: Singer) in
Text("\(singer.firstName ?? "") \(singer.lastName ?? "")")
}.environment(\.managedObjectContext, (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext)
}

关于ios - SwiftUI 中的动态过滤器(谓词),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59501638/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com