SwiftUI - 在谓词中使用从先前视图传递的值
SwiftUI - Use value passed from previous view in predicate
所以我是 SwiftUI 的新手。通常我会在 viewdidload 方法中收到获取请求,但现在不确定如何处理它,因为该方法似乎没有等效方法。
所以我有一个视图,我正在将一个变量传递给另一个视图,就像这样
NavigationLink(destination: ItemAddView(series: series)) {
Label("Add Item", systemImage: "plus")
}
我现在想在获取请求的谓词中使用这个变量。
获取请求设置如下
struct ItemAddView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Item.name, ascending: true)],
animation: .default)
private var items: FetchedResults<Item>
var series: Series
@State private var searchText = ""
var body: some View {
List {
ForEach(items) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
Image(item.mainImage ?? "")
.renderingMode(.original)
.resizable()
.scaledToFit()
.frame(width: 100.0)
Text("\(item.name ?? "Error")")
}
}
}
.searchable(text: $searchText)
.onSubmit(of: .search) {
items.nsPredicate = NSPredicate(format: "series = %@", series)
if(!searchText.isEmpty) {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount = 0 AND name CONTAINS[cd] %@", series, searchText)
}
}
.onChange(of: searchText) { _ in
items.nsPredicate = NSPredicate(format: "series = %@", series)
if(!searchText.isEmpty) {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount = 0 AND name CONTAINS[cd] %@", series, searchText)
}
}
.navigationBarTitle("\(series.name ?? "Error") Add Items", displayMode: .inline)
.onAppear() {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount = 0", series)
}
}
}
如果我在这里使用谓词,我会得到一个错误
Cannot use instance member 'series' within property initializer; property initializers run before 'self' is available
我已经习惯于在 onAppear 方法中使用谓词
.onAppear() {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount > 0", series)
}
但问题是我看到了完整列表,然后才转到过滤后的请求。这样做的正确方法是什么?
您只需在header中声明变量即可。然后您可以在 init() 中进行初始化并使用传入的变量。如果您随后不需要 series
,则不需要在视图中有任何变量来分配给它。此外,由于您没有 post 完整视图,我不得不猜测 series
.
的类型
struct ItemAddView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest private var items: FetchedResults<Item>
init(series: Series) {
let request = Item.fetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.name, ascending: true)], predicate: NSPredicate(format: "series = %@ AND amount > 0", series), animation: .default)
_items = FetchRequest(fetchRequest: request)
// Initialize anything else that is necessary
}
...
}
所以我是 SwiftUI 的新手。通常我会在 viewdidload 方法中收到获取请求,但现在不确定如何处理它,因为该方法似乎没有等效方法。
所以我有一个视图,我正在将一个变量传递给另一个视图,就像这样
NavigationLink(destination: ItemAddView(series: series)) {
Label("Add Item", systemImage: "plus")
}
我现在想在获取请求的谓词中使用这个变量。 获取请求设置如下
struct ItemAddView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Item.name, ascending: true)],
animation: .default)
private var items: FetchedResults<Item>
var series: Series
@State private var searchText = ""
var body: some View {
List {
ForEach(items) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
Image(item.mainImage ?? "")
.renderingMode(.original)
.resizable()
.scaledToFit()
.frame(width: 100.0)
Text("\(item.name ?? "Error")")
}
}
}
.searchable(text: $searchText)
.onSubmit(of: .search) {
items.nsPredicate = NSPredicate(format: "series = %@", series)
if(!searchText.isEmpty) {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount = 0 AND name CONTAINS[cd] %@", series, searchText)
}
}
.onChange(of: searchText) { _ in
items.nsPredicate = NSPredicate(format: "series = %@", series)
if(!searchText.isEmpty) {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount = 0 AND name CONTAINS[cd] %@", series, searchText)
}
}
.navigationBarTitle("\(series.name ?? "Error") Add Items", displayMode: .inline)
.onAppear() {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount = 0", series)
}
}
}
如果我在这里使用谓词,我会得到一个错误
Cannot use instance member 'series' within property initializer; property initializers run before 'self' is available
我已经习惯于在 onAppear 方法中使用谓词
.onAppear() {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount > 0", series)
}
但问题是我看到了完整列表,然后才转到过滤后的请求。这样做的正确方法是什么?
您只需在header中声明变量即可。然后您可以在 init() 中进行初始化并使用传入的变量。如果您随后不需要 series
,则不需要在视图中有任何变量来分配给它。此外,由于您没有 post 完整视图,我不得不猜测 series
.
struct ItemAddView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest private var items: FetchedResults<Item>
init(series: Series) {
let request = Item.fetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.name, ascending: true)], predicate: NSPredicate(format: "series = %@ AND amount > 0", series), animation: .default)
_items = FetchRequest(fetchRequest: request)
// Initialize anything else that is necessary
}
...
}