概述
我用核心数据做一个简单的应用程序,我有两个实体用户,并且该应用程序按地区显示了按地区划分的用户列表,问题是在删除操作中,如果我尝试从第一部分中删除用户从第二部分中删除第二个用户,从第一部分中删除第二个用户。
我认为发送该部分的索引的索引集出错,但是当我尝试将onDelete更改为嵌套的forEach不起作用
这是代码
import SwiftUI
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: User.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \User.name, ascending: true)]) var users: FetchedResults<User>
@FetchRequest(entity: Territory.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Territory.name, ascending: true)]) var territories: FetchedResults<Territory>
@State private var showAddUser = false
var body: some View {
GeometryReader{ geometry in
NavigationView {
ZStack {
List {
ForEach(self.territories, id: \.self) { territorie in
Section(header: Text(territorie.wrappedName)) {
ForEach(territorie.usersArray, id: \.self) { user in
NavigationLink(destination: UserView(user: user)) {
VStack{
HStack{
Text("user")
Spacer()
Text(user.dayLastVisit)
.padding(.horizontal)
}
HStack {
Text(user.wrappedEmoji)
.font(.largeTitle)
VStack(alignment: .leading) {
Text("\(user.wrappedName + " " + user.wrappedLastName)")
.font(.headline)
Text(user.wrappedType)
}
Spacer()
}
}
}
}.onDelete(perform: self.deleteItem)
}
}
}
.listStyle(GroupedListStyle())
.environment(\.horizontalSizeClass, .regular)
VStack {
Button(action:{ self.showAddRUser.toggle()}){
ButtonPlus(icon:"plus")}
.offset(x: (geometry.size.width * 0.40), y: (geometry.size.height * 0.38))
.sheet(isPresented: self.$showAddUser){
NewUserView().environment(\.managedObjectContext, self.moc)
}
}
}
.navigationBarTitle("Users")
.navigationBarItems( trailing: HStack {
EditButton()
Button(action:{self.showAddUser.toggle()}){
ButtonNew(text:"Nueva")}
}
.sheet(isPresented: self.$showAddUser){
NewUserView().environment(\.managedObjectContext, self.moc)
}
)
}
}
}
func deleteItem(at offsets: IndexSet) {
for offset in offsets {
let user = users[offset]
//borarlo del context
moc.delete(user)
}
try? moc.save()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我正在学习swift和swiftui,因此我将不胜感激
答案 0 :(得分:3)
您需要传递部分索引和行索引,以便知道要删除的嵌套项目。这样的事情。
.onDelete { self.deleteItem(at: $0, in: sectionIndex) }
并更改您的函数以接受该部分索引:
func deleteItem(at offsets: IndexSet, in: Int)
在您的情况下,您可以传入territorie.id
之类的内容作为部分索引,并使用它来删除正确的项目。或传递territorie
对象-获得正确用户所需的一切。只有索引不会让您到达那里。希望这一切有意义!
答案 1 :(得分:1)
因此,在凯文·伦斯克斯(Kevin Renskers)的帮助下,o找到了一个解决方案,我只需在函数中添加.onDelete { self.deleteItem(at: $0, in: territorie)}
,然后使用来自该地区的相同arrayUsers。
func deleteItem(at offsets: IndexSet, in ter: Territory) {
for offset in offsets {
let user = ter.usersArray[offset]
moc.delete(user)
}
try? moc.save()
}
答案 2 :(得分:1)
对我来说,解决方法如下:
ForEach(self.territories, id: \.self) { territorie in
Section(header: Text(territorie.wrappedName)) {
ForEach(territorie.usersArray, id: \.self) { user in
// your code here
}
.onDelete { indexSet in
for index in indexSet {
moc.delete(territorie[user])
}
// update the view context
moc.save()
}
}
}
index
中的indexSet
返回应在该特定部分中删除的项目。因此,如果我删除某节的第一项,它将返回0。
territorie
返回该部分中包含的所有项目的列表。因此,使用territorie [index]将返回您要删除的特定用户对象。
现在我们有了要删除的对象,我们可以将其传递给moc.delete(territorie[index])
。最后,我们用moc.save()
保存它。
旁注:尽管Misael使用了变量“ territorie”,但我更喜欢使用变量名section
。