@kitty wonders:
[How does one] delete an item in a grid view using an alert?
Trust the Collection
You don't show much code, but here's something to think about. You don't delete a book from the grid view. You delete a book from a collection. The collection will inform the view that it has changed. The view will respond by re-drawing itself.
If you want to delete a book using an alert, you (somehow) need to capture the individually selected book. THEN, you need to ask the data model to delete the selected element.
Here's an example I worked on to illustrate. This demo displays a number of books in a library. You can swipe to delete a book. Or you can delete a random book. Or you can delete a random book by Stephen King.
In each of these examples, the view sends the delete request to the collection. The details of deleting the book is left to the collection. One of the options, the swipe option, asks the collection to delete a specific book. The other two options ask the collection to delete random books.
struct LibraryView: View {
@ObservedObject var library = Books() // init a local collection of books
var body: some View {
VStack {
Text("Books in my Library").font(.largeTitle)
List {
ForEach(library.allBooks) { book in BookView(aBook: book) }
.onDelete(perform: library.deleteBook) // 👈🏼 Delete a specific book
.padding(.vertical)
}
Spacer()
VStack {
Button("Delete Random Book") {
// Please note! You delete a book from the library.
library.deleteBook(at: library.randomBookInLibrary())
}.padding()
Button("Delete King Book") {
// Please note! You delete a book from the library.
library.deleteRandomKingBook()
}
.disabled(library.kingBookCount == 0)
}.buttonStyle(BorderedProminentButtonStyle())
}
}
}
struct BookView: View {
let aBook: Book // 👈🏼 Show just this book
var body: some View {
HStack {
Text(aBook.title).font(.headline); Spacer()
Text(aBook.author).font(.subheadline)
}
}
}
#Preview { LibraryView() }
// Trust the Books model!
// It knows how to delete a book from its collection.
// Don't let other structs delete a book.
class Books: ObservableObject {
@Published var allBooks: [Book] = sampleBooks
// You don't delete a book from the view!
// You delete a book from the book collection!
// The view will update itself when the collection changes.
public func deleteBook(at indexSet: IndexSet) {
allBooks.remove(atOffsets: indexSet)
}
// Trust the collection!
// It knows how many Stephen King books it has!
public var kingBookCount: Int { allBooks.filter { $0.author.contains("King") }.count }
public func randomBookInLibrary() -> IndexSet {
let randomIndex = Int.random(in: 0..<allBooks.count)
// return ONE random book in the entire library
return IndexSet(integer: randomIndex)
}
public func deleteRandomKingBook() {
// Get all Stephen King books.
let kingBooks: [Book] = allBooks.filter{ $0.author.contains("King") }
// Get one random King book, if there are any in the library
if !kingBooks.isEmpty {
let randomKingBook = kingBooks[Int.random(in: 0..<kingBooks.count)]
// Find the index in the allBooks collection
if let randomKingBookIndex = allBooks.firstIndex(where: { $0.id == randomKingBook.id }) {
// Delete the book at that index
deleteBook(at: IndexSet(integer: randomKingBookIndex))
}
}
}
}
// These are examples to use whilst coding.
extension Books {
static let sampleBooks: [Book] =
[
Book(id: 0, title: "The Great Gatsby", author: "F. Scott Fitzgerald"),
Book(id: 1, title: "It", author: "Stephen King"),
Book(id: 2, title: "Needful Things", author: "Stephen King"),
Book(id: 3, title: "The Dome", author: "Stephen King"),
Book(id: 42, title: "The Hitchhiker's Guide to the Galaxy", author: "Douglas Adams"),
Book(id: 5, title: "Mostly Harmless", author: "Douglas Adams"),
Book(id: 6, title: "SwiftUI By Example", author: "Paul Hudson"),
Book(id: 7, title: "Swift Coding Challenges", author: "Paul Hudson"),
Book(id: 8, title: "Night Shift", author: "Stephen King"),
]
}
// Describe just one book in the collection
struct Book: Identifiable, Equatable {
var id: Int
let title: String
let author: String
}
Keep Coding
Please return here and let us know if this sample was useful. Also, we'd like to know what solution you implemented!