在我的ListView中,有一个由复选框,文本,间隔符和删除按钮组成的HStack。不幸的是,单击HStack的任何部分(复选框/文本/间隔区域)导致删除按钮动作触发。如何限制这个删除动作只适用于删除按钮,而不是整个HStack视图在SwiftUI ListView?
extension View {
@ViewBuilder public func hidden(_ shouldHide: Bool) -> some View {
switch shouldHide {
case true: self.hidden()
case false: self
}
}
}
struct AgendaItem: Identifiable {
let id = UUID()
var title: String
var isSelected = false
}
struct AgendaList: View {
@State private var agendaItems = [AgendaItem]()
@State private var newAgendaItem = ""
var body: some View {
VStack {
Text("Agenda List")
.font(.title)
HStack {
ZStack(alignment: .topLeading) {
TextEditor(text: $newAgendaItem)
.frame(height: 40)
.overlay(
RoundedRectangle(cornerRadius: 3)
.stroke(Color(UIColor.opaqueSeparator), lineWidth: 0.5)
)
Text("Add agenda")
.fontWeight(.light)
.foregroundColor(.black.opacity(0.25))
.padding(8)
.hidden(!newAgendaItem.isEmpty)
}
Button(action: addItem) {
Text("Add")
}
.padding(.horizontal)
}
.padding()
List(agendaItems) { agendaItem in
HStack(alignment: .top, spacing: 8) {
VStack {
CheckBox(isChecked: $agendaItems[getIndex(for: agendaItem.id)].isSelected)
.padding(.top, 3)
Spacer()
}
Text(agendaItem.title)
.strikethrough(agendaItem.isSelected)
Spacer()
Button(action: {
deleteItem(at: getIndex(for: agendaItem.id))
}) {
Image(systemName: "trash")
}
}
}
.listRowBackground(Color.red)
}
}
func addItem() {
agendaItems.append(AgendaItem(title: newAgendaItem))
newAgendaItem = ""
}
func getIndex(for id: UUID) -> Int {
return agendaItems.firstIndex { $0.id == id } ?? 0
}
func deleteItem(at index: Int) {
agendaItems.remove(at: index)
}
}
struct CheckBox: View {
@Binding var isChecked: Bool
var body: some View {
Button(action: {
isChecked.toggle()
}) {
Image(systemName: isChecked ? "checkmark.square.fill" : "square")
.foregroundColor(isChecked ? .blue : .gray)
}
}
}
可以通过为按钮添加以下两个属性来实现:
Button(action: {
deleteItem(at: getIndex(for: agendaItem.id))
}) {
Image(systemName: "trash")
}
.onTapGesture { }
.buttonStyle(BorderlessButtonStyle())
Button视图的buttonStyle属性被设置为BorderlessButtonStyle来移除按钮的背景。onTapGesture修饰符被添加到Button视图来处理点击事件,一个空闭包被提供给onTapGesture修饰符来防止列表行被点击。
您可以通过将.buttonStyle(...)
添加到HStack
中的Button
来实现所需的行为。
struct ContentView: View {
var items = ["Item 1", "Item 2", "Item 3"]
var body: some View {
List(items, id: .self) { item in
HStack {
Text(item)
Spacer()
Button("click me") {
print("(item) button tapped")
}
.buttonStyle(.borderless)
}
}
}
}