简体   繁体   English

SwiftUI 通过 ForEach 中的按钮将数据移入结构化数组

[英]SwiftUI remove data into a structured array via a button in a ForEach

I'm trying to remove a line in my structured array when user click on the delete button.当用户单击删除按钮时,我试图删除结构化数组中的一行。 But as I use a foreach to load all my array lines into a specific subview I don't know how to pass the index of the ForEach into my subview to delete my line...但是当我使用 foreach 将我所有的数组行加载到特定的子视图中时,我不知道如何将 ForEach 的索引传递到我的子视图中以删除我的行......

My code is like this,我的代码是这样的

ScrollView{
                VStack {
                    ForEach(planeLibrary.testPlane){plane in
                        ZStack {
                            RoundedRectangle(cornerRadius: 16, style: .continuous)
                                .fill(Color.white)
                                .shadow(color: Color(Color.RGBColorSpace.sRGB, white: 0, opacity: 0.2), radius: 4)
                            
                            PlaneCellView(plane: plane, planeLibrary: planeLibrary, line: ???)
                        }
                    }
                }.padding(.horizontal, 16)
            } 

And my PlaneCellView:还有我的 PlaneCellView:

@State var plane: Plane
@ObservedObject var planeLibrary: PlaneLibrary
var line: Int
var body: some View {
//...
VStack(alignment: .leading) {
                Text(plane.planeImat)
                    .font(.title)
                    .fontWeight(.bold)
                Text(plane.planeType)
                HStack{
                    Text(plane.isSe ? "SE" : "ME")
                    Text(plane.isNight ? "-  Night" : "")
                    Text(plane.isIfr ? "-  IFR" : "")
                }
            }
            Spacer()
            Button {
               // HERE I don't know how to delete my array line ...
               planeLibrary.testPlane.remove(at: line) 
            } label: {
                 Image(systemName: "trash.circle")
                       .foregroundColor(.red)
                       .font(.system(size: 30))
            }
//...
}

My Plane library:我的飞机库:

struct Plane: Identifiable{
    let id = UUID().uuidString
    let planeImat: String
    let planeType: String
    let isSe: Bool
    let isIfr: Bool
    let isNight: Bool
    let autoID: String
    
    init (planeImat: String, planeType: String, isSe: Bool, isIfr: Bool, isNight: Bool, autoID: String){
        self.planeType = planeType
        self.planeImat = planeImat
        self.isSe = isSe
        self.isIfr = isIfr
        self.isNight = isNight
        self.autoID = autoID
    }
    
    init(config: NewPlaneConfig){
        self.planeImat = config.imat
        self.planeType = config.type
        self.isSe = config.isSe
        self.isIfr = config.isIfr
        self.isNight = config.isNight
        self.autoID = config.autoID
    }
}

I've already try to add id: \.self as I was able to find on this forum but without any success.我已经尝试添加id: \.self因为我能够在这个论坛上找到但没有成功。

You haven't actually included PlaneLibrary, so I will assume that planeLibrary.testPlane is an array of Plane structs.您实际上还没有包含 PlaneLibrary,所以我假设 planeLibrary.testPlane 是一个 Plane 结构数组。

There are many ways of solving this, including changing testPlane to be a Dictionary of Plane structs (indexed by id), or if order is important, in an OrderedDictionary (add the swift-collections package to your project and import OrderedCollections in the file where it is used).有很多方法可以解决这个问题,包括将 testPlane 更改为平面结构字典(由 id 索引),或者如果顺序很重要,则在 OrderedDictionary 中(将swift-collections package添加到您的项目并在文件中import OrderedCollections它被使用)。 You could use testPlane.removeValue(at: id) to remove the plane from either type of dictionary.您可以使用testPlane.removeValue(at: id)从任一类型的字典中删除平面。

If you keep it as an array, but your array might be large and you're worried about run-time efficiency, the best thing to do is to change your ForEach to include the index of the planes in the loop.如果您将它保存为一个数组,但您的数组可能很大并且您担心运行时效率,最好的办法是更改您的 ForEach 以在循环中包含平面的索引。

It would look something like this:它看起来像这样:

ForEach(Array(planeLibrary.testPlane.enumerated()), id: \.element.id) { index, plane in
    // In this code you can use either plane, or index.
    ...
    // UI code
    Text(plane.autoID)
    ...
    { // remove closure
         planeLibrary.testPlane.remove(at: index)
    }
}

But if the array is of reasonable size, you could keep it as it is now and use testPlane.remove(where:) to find it by id at the time of deletion.但是如果数组的大小合理,你可以保持它现在的样子,并在删除时使用testPlane.remove(where:)通过id找到它。 The code for this is much simpler and easier to read and understand, so it should probably be your first choice.这样做的代码更简单,更容易阅读和理解,因此它应该是您的首选。 Optimise for large lists later, if you need.如果需要,稍后针对大型列表进行优化。

You can't pass the index in because that will crash the ForEach View.您不能传入索引,因为这会使ForEach视图崩溃。 Instead, look up its index using its ID afterwards to remove it, eg相反,之后使用其 ID 查找其索引以将其删除,例如

class RecipeBox: ObservableObject {
    @Published var allRecipes: [Recipe]
    @Published var collections: [String]

...

    func delete(_ recipe: Recipe) {
        delete(recipe.id)
    }
    
    func delete(_ id: Recipe.ID) {
        if let index = index(for: id) {
            allRecipes.remove(at: index)
            updateCollectionsIfNeeded()
        }
    }
...
    func index(for id: Recipe.ID) -> Int? {
        allRecipes.firstIndex(where: { $0.id == id })
    }
...

This sample is from Defining the source of truth using a custom binding (Apple Developer)此示例来自使用自定义绑定定义真实来源(Apple Developer)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SwiftUI 删除 ForEach 子视图中的数组条目 - SwiftUI remove array entries within ForEach subviews 更改所选按钮颜色 SwiftUI ForEach 数组 - Change Selected Button Color SwiftUI ForEach Array 在 SwiftUI 中循环遍历实体数组以基于数组数据中的值构建树结构视图 - Loop through entity array in SwiftUI to build tree-structured view based on values in array data 为什么我不能访问这个数组 ForEach 循环中的数据? 用户界面 - Why cannot I not access the data in this array ForEach loop? SwiftUI 删除数组 Swiftui 中的值 - remove value in array Swiftui [SwiftUI]:ForEach 不适用于字典数组、带有数组的字典 - [SwiftUI]: ForEach is not working for array of dictionary, dictionary with array SwiftUI:3 次尝试使用 ForEach 从 model 数据迭代数组产生整个数组 - SwiftUI: 3 attempts using ForEach to iterate array from model data produces entire array CSV 数据到 Numpy 结构化数组? - CSV data to Numpy structured array? 通过列数据上的逐位操作(位掩码)过滤结构化阵列 - Filtering of structured array via bit-wise operation (bitmask) on column data SwiftUI - 将结构化数组排序并显示日期项到一个部分 Header - SwiftUI - Sorting a structured array and show date item into a Section Header
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM