试图制作成排的 3 列可删除按钮,但有些东西在这里不起作用

Posted

技术标签:

【中文标题】试图制作成排的 3 列可删除按钮,但有些东西在这里不起作用【英文标题】:Tried to make rows of 3-column deletable buttons, but something doesn't work here 【发布时间】:2020-06-15 13:24:05 【问题描述】:

我尝试在 VStack 中制作多行 3 列按钮。它在this post 中工作,在我重写了解决方案以使按钮出现在一行 3 列中之后,它不再工作 - 当我单击“删除按钮”时,额外的垃圾图像不会出现在每个按钮上。这里有什么问题吗?

class SomeData: ObservableObject
    @Published var buttonObjects: [ButtonObject] = [ButtonObject(name: "tag1", isSelected: false),
                                                   ButtonObject(name: "tag2", isSelected: false), ButtonObject(name: "tag3", isSelected: false), ButtonObject(name: "tag4", isSelected: false)]
    

struct someData3: View 
    @Environment(\.editMode) var mode
    @ObservedObject var someData = SomeData()
    @State var newButtonTitle = ""
    @State var isEdit = false

    var body: some View 
        NavigationView
//            List // VStack
                VStack
                    VStack(alignment: .leading)
                            ForEach(0..<someData.buttonObjects.count/3+1)  row in // create number of rows
                                HStack
                                    ForEach(0..<3)  column in // create 3 columns
                                        self.makeView(row: row, column: column)
                                    
                                
                            
                        



                    HStack
                        TextField("Enter new button name", text: $newButtonTitle)
                            let newObject = ButtonObject(name: self.newButtonTitle, isSelected: false)
                            self.someData.buttonObjects.append(newObject)
                            self.newButtonTitle = ""
                        
                    

                    Spacer()

                    HStack
                        Text("isEdit is ")
                        Text(String(self.isEdit))
                        
                
                .navigationBarItems(leading: Button(action: self.isEdit.toggle())Text("Delete Button"),
                                 trailing: EditButton())


                




    


    func makeView(row: Int, column: Int) -> some View
        let ind = row * 3 + column
        return Group
            if ind<self.someData.buttonObjects.count 
                   Button(action: 
                    self.someData.buttonObjects[ind].isSelected = !self.someData.buttonObjects[ind].isSelected
                    print("Button pressed! buttonKeyName is: \(self.someData.buttonObjects[ind].name) Index is \(ind)")
                    print("bool is \(self.someData.buttonObjects[ind].isSelected)")

                   ) 

                    Text(self.someData.buttonObjects[ind].name)

                   
                   .buttonStyle(GradientBackgroundStyle(isTapped: self.someData.buttonObjects[ind].isSelected))
                    .overlay(Group 
                         if self.isEdit 
                             ZStack 
                                 Button(action: self.deleteItem(ind: ind)) 
                                    Image(systemName: "trash")
                                         .foregroundColor(.red).font(.title)
                                 .padding(.trailing, 40)
                                    .alignmentGuide(.top)  $0[.bottom] 
                             .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing) //topTrailing

                            
                        
                    )
                   .padding(.bottom, 20)


            
            else
                EmptyView()

            
        

    


    func deleteItem(ind: Int) 
        let name = someData.buttonObjects[ind].name
        print(" deleting ind \(ind), key: \(name)")
        self.someData.buttonObjects.remove(at: ind)
       



【问题讨论】:

@Asperi 介意看看这里吗? 【参考方案1】:

您可以在 ForEach 末尾添加显式 .id - 因为您使用的是静态 ForEach,您可能需要强制刷新它。

在您之前的帖子中,您使用了动态ForEach(带有id 参数)。这就是它起作用的原因。

ForEach(0 ..< someData.buttonObjects.count / 3 + 1)  row in // create number of rows
    HStack 
        ForEach(0 ..< 3)  column in // create 3 columns
            self.makeView(row: row, column: column)

        
    

.id(UUID()) // <- add this line

【讨论】:

添加该行后,会显示垃圾图像,但是当您点击它时,什么都不会发生。 这看起来像是一个不同的问题。 当我单击“删除按钮”时,附加垃圾图像不会出现在每个按钮上。这里有什么问题吗? - 我想我回答了你的问题。 对于用户新创建的按钮,可以在点击垃圾图像时将其删除。但是对于第一行的默认标签( tag1, tag2, tag3 ),当您点击垃圾图像时没有任何反应。 您遇到的问题可能与.alignmentGuide(.top) $0[.bottom] 有关。如果您删除此行,它将起作用。但我之前想说的是,这个问题应该作为另一个问题发布。 不,我仍然希望保留该行,因为垃圾图像应该稍微出现在按钮的顶部。我意识到,当您像这样添加 Spacer() 时:VStackSpacer()VStack(alignment: .leading)...),那么一切正常。似乎在不添加 Spacer() 的情况下,有些东西禁止在第一行的前 3 个按钮上点击垃圾图像。

以上是关于试图制作成排的 3 列可删除按钮,但有些东西在这里不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何编写程序来生成排序决策树?

如何让我的 X 按钮删除数组中的特定对象?

flex 属性与按钮高度混淆?

试图制作我在 CSS 中完成但失败的代码的动画幻灯片

在 Android 中动态创建/删除按钮

试图制作一个二维数组列表