试图制作成排的 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 列可删除按钮,但有些东西在这里不起作用的主要内容,如果未能解决你的问题,请参考以下文章