El modificador swipeActions(edge:allowsFullSwipe:content:) define las acciones de "swipe" para una fila de una lista. edge (.trailing por defecto) señala el lado donde aparecerán. Si allowsFullSwipe = true (valor por defecto), ejecuta la primera acción cuando se hace "swipe" completo. content son los botones que representan las acciones.
struct ContentView: View {
@State var contacts: [Contact] = [
.init(name: "Luis"),
.init(name: "David"),
.init(name: "Goyes"),
.init(name: "Garcés"),
]
@State var selectedContacts: Set<Contact.ID> = []
@State var editing: EditMode = .inactive
var body: some View {
NavigationStack {
List(selection: $selectedContacts) {
ForEach(contacts) { contact in
Text(contact.name)
.swipeActions {
// ⚠️ Esta es la primera acción, de derecha a izquierda
Button(role: .destructive) {
contacts.removeAll { $0.id == contact.id }
} label: {
Image(systemName: "trash")
}
Button {
print("Editando")
} label: {
Image(systemName: "pencil")
}
.tint(Color.yellow)
// ⚠️ Se usa .tint() para cambiar el color de fondo de la acción.
}
}
}
.environment(\.editMode, $editing)
.deleteDisabled(false)
.toolbar {
Button {
editing = (editing == .inactive) ? .active : .inactive
} label: {
Text(editing == .active ? "Listo" : "Editar")
}
Button {
let indexes = selectedContacts.compactMap { id in
contacts.firstIndex { $0.id == id }
}.reduce(into: IndexSet()) { partialResult, index in
partialResult.insert(index)
}
contacts.remove(atOffsets: indexes)
selectedContacts = []
editing = .inactive
} label: {
Label {
Text("Eliminar")
} icon: {
Image(systemName: "trash")
}
}.disabled(selectedContacts.count == 0)
}
}
}
}

SOCIAL SHARE CARD GENERATOR