#ios #core-data #swiftui #contextmenu #delete-row
#iOS #core-data #SwiftUI #Контекстное меню #удалить-строка
Вопрос:
Впервые публикую здесь и новичок в кодировании… поэтому я надеюсь, что я следую правильному протоколу. Я собираю представление в Xcode 12.2 (SwiftUI 2), которое выводит список данных из Core Data и имеет контекстное меню, чтобы предоставить пользователю возможность редактировать, удалять и удалять несколько. Контекстное меню работает правильно для редактирования и удаления, однако я сталкиваюсь с препятствием в реализации функциональности для удаления нескольких элементов списка. Я предполагаю, что пользователь сильно нажмет на один из элементов списка, откроется контекстное меню, и если они нажмут опцию «Удалить несколько», представление активирует что-то похожее на режим редактирования, который заполняет маленький круг слева от каждого элемента, который пользователь может выбрать и удалить более одного элементаодновременно. Я могу увидеть другую статью о том, как это сделать, однако я не могу найти указаний о том, как реализовать это с помощью Core Data. Я вставил свой код ниже.
Пожалуйста, дайте мне знать, если мне не хватает какой-либо другой информации, которая сделала бы мой вопрос более понятным.
Я действительно ценю опыт и рекомендации форумов.
Struct List : View {
@StateObject var appData = AppViewModel()
@Environment(.managedObjectContext) var context
//Fetch Data...
@FetchRequest(entity: EntryData.entity(), sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)], animation: .spring()) var results : FetchedResults<EntryData>
var body : some View {
ZStack(alignment: Alignment(horizontal: .trailing, vertical: .bottom), content: {
VStack{
ScrollView(.vertical, showsIndicators: false, content: {
LazyVStack(alignment: .leading, spacing: 20){
ForEach(results){task in
VStack(alignment: .leading, spacing: 5, content: {
Text(task.category ?? "")
.font(.title)
.fontWeight(.bold)
Text(task.date ?? Date(), style:. date)
.fontWeight(.bold)
Text("(task.number.formattedCurrencyText)")
})
.padding(.horizontal, 14)
.padding(.top, 10)
.foregroundColor(Color("ColorTextList"))
.contextMenu{
Button(action: {appData.editItem(item: task)}, label: {
Text("Edit")
})
Button(action: {
context.delete(task)
try! context.save()
}, label: {
Text("Delete")
})
Button(action: {}, label: {
Text("Delete Mutiple")
})
}
}
}
})
}
VStack(){
VisualEffectView(effect: UIBlurEffect(style: .regular))
.frame(width: UIScreen.main.bounds.width, height: 50, alignment: .top)
.edgesIgnoringSafeArea(.all)
.background(Color.clear)
Spacer()
}
})
.background(Color.clear)
.sheet(isPresented: $appData.isNewData, content: {
AddDataView(appData: appData)
.environment(.managedObjectContext, self.context)
})
}
}
Добавление ViewModel приложения. Как мне подключиться к этому и удалить каждый из атрибутов в выборе из нескольких списков?
import SwiftUI
import CoreData
class AppViewModel : ObservableObject, Identifiable{
@Published var cateogry = ""
@Published var date = Date()
@Published var number : Double? = nil
@Published var notes = ""
@Published var id = UUID()
}
И добавление фактического скриншота модели Core Data.
Ответ №1:
Вы можете реализовать набор выбора для своего списка. Это будет содержать все выбранные элементы. Затем вы можете динамически отображать контекстное меню для удаления или удаления всего на основе количества набора. Вот полный пример с реализацией deleteAll
struct SelectionDemo : View {
@State var demoData = ["Dave", "Tom", "Phillip", "Steve"]
@State var selected = Set<String>()
var body: some View {
HStack {
List(demoData, id: .self, selection: $selected){ name in
Text(name)
.contextMenu {
Button(action: {
//Delete only one item
}){
Text("Delete")
}
if (selected.count > 1) {
Button(action: {
//Delete all
deleteAll()
})
{
Text("Delete all")
}
}
}
}.frame(width: 500, height: 460)
}
}
func deleteAll() {
for element in selected {
self.demoData.removeAll(where: {
$0 == element
})
}
}
}
Комментарии:
1. Спасибо! Тем не менее, я скопировал ваш код, и я не могу выбрать несколько строк и отобразить всплывающую функцию удаления всех. Когда я долго нажимаю на элемент, все, что я получаю, это удалить. Как выбрать несколько элементов, не переходя в «режим редактирования», аналогичный NavigationView? Кроме того, будет ли это работать для элементов, хранящихся в основных данных, В которых более одного файла (например, имя, дата, сумма и т. Д.)? Я делаю что-то не так?
2. больше возился с этим. Я предполагаю, что я застрял в функции deleteAll(), строке self.demoData.removeAll. Я не уверен, как связать его с основной базой данных, чтобы удалить выбранные элементы. В вашем примере это ссылка на массив с одним полем (т.Е. Именем). Когда я заменяю демоданные на мои результаты FetchedResults (т.Е. Результаты var), я получаю сообщение об ошибке «Значение типа’FetchedResults<EntryData>’ не имеет элемента ‘removeAll'». EntryData — это имя моего объекта CoreData. Ценю ваши рекомендации и отзывы.