В списке Swift-UI (iOS), показывающем некоторые элементы CoreData, я хочу показать всплывающее окно для каждого элемента для изменения атрибута элемента CoreData.
В приведенном ниже коде это невозможно закрыть всплывающее окно.
Если я удаляю .id(UUID())
из списка, он работает нормально.
В моем приложении требуется .id(UUID())
, потому что я изменяю предикат "на fly "и это единственный способ, который я знаю, чтобы избежать того, что SwiftUI пытается сравнить все элементы List старого и нового результата. Эта проблема производительности обсуждалась в Проблема производительности со списком SwiftUI
Есть идеи, как решить эту проблему?
import Foundation
import SwiftUI
struct ContentView: View {
@FetchRequest(entity: Item.entity(), sortDescriptors: [], predicate: nil) var items: FetchedResults<Item>
var body: some View {
VStack
{ Button("Create Testdata"){createTestdata()}
List(items, id: \.self)
{ item in
Line(item: item)
}.id(UUID())
}
}
}
struct Line: View {
@ObservedObject var item : Item
@State var showSheet = false
var body: some View {
Text(item.text!)
.onLongPressGesture {
self.showSheet.toggle()// = true
}
.popover( isPresented: self.$showSheet,
arrowEdge: .trailing
)
{ Pop(showSheet: self.$showSheet, item: self.item )
}
}
}
struct Pop: View {
@Binding var showSheet: Bool
var item : Item
//@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack {
Text("CHANGE TO XXXXXXXXX")
.onTapGesture
{ self.item.text = "XXXXXXX"
self.showSheet = false
}
Text("CHANGE TO YYYYYYYYY")
.onTapGesture
{ self.item.text = "YYYYYY"
self.showSheet = false
}
Button("Cancel")
{
#if os(OSX)
NSApp.sendAction(#selector(NSPopover.performClose(_:)), to: nil, from: nil)
#else
//self.presentationMode.wrappedValue.dismiss() // << behaves the same as below
self.showSheet = false
#endif
}
}
}
}