Лист от Lazyvgrid.. снова

Я знаю, что об этом уже спрашивали, но я просто не могу понять, почему это не работает для меня. Я довольно новичок в кодировании, поэтому любая помощь будет оценена по достоинству.

Попытка открыть BookSheetView как лист после выбора ячейки в моей lazyvgrid.

      struct LibraryView: View {
    @State private var showingSheet = false
    
    let book: Book
    
    let spacing: CGFloat = 10
    
    var gridItems: [GridItem] {
        [GridItem(.adaptive(minimum: 180, maximum: 180))]
    }
    
    var body: some View {
        Text("Text to come")
            .multilineTextAlignment(.leading)
            .navigationTitle("Library")        
        
        ScrollView {
            LazyVGrid(columns: gridItems,
                      spacing: spacing
            )
            { ForEach(books, id: \.self) { book in
                
                Button {
                    showingSheet = true
                } label: {
                    BookTileModel(book: book)
                }
                
                //                NavigationLink(destination: BookSheetView(book:book),
                //                               label: {BookTileModel(book: book)})
                
            }
            }
        }
        //  Start of sheet
        .sheet(isPresented: $showingSheet) {
            BookSheetView(book: book)
        }
        // End of sheet
    }
    
}

struct LibraryView_Previews: PreviewProvider {
    static var previews: some View {
        LibraryView(book: books[1])
    }
}

Если я использую кнопку, я могу заставить лист открываться в правильном виде, но это не передает информацию листу, и если я использую NavigationLink, я получаю правильную информацию, но как полную страницу, а не лист .

Я просмотрел кучу похожих постов и посмотрел несколько руководств, но я просто не могу понять это :(

ОБНОВЛЕННЫЙ КОД

      import Foundation
import SwiftUI

extension String: Identifiable {
    public var id: String { self }
}

struct GridView: View {

    @State private var selected: String? = nil

    let book: Book

    var gridItems: [GridItem] {
        [GridItem(.adaptive(minimum: 180, maximum: 180))]
    }

    var body: some View {

        ScrollView (showsIndicators: false) {
                        LazyVGrid(columns: gridItems) {
                            ForEach(book, id: \.self) { item in   //ERROR Generic struct 'ForEach' requires that 'Book' conform to 'RandomAccessCollection'

                                Button(action: {
                                    selected = item
                                }) {
                                    BookTileModel(book: book)
                                }
                            }
                        }
                    }.sheet(item: $selected) { item in
                        BookSheetView(book: item)  // ERROR Cannot convert the value of type 'String' to expected argument type 'Book'
                    }
                 
                }
            }

1 ответ

Вот рабочий пример, обратите внимание на комментарии:

      struct ContentView: View {
    
    let books: [Book] = [
        Book(title: "Anna Karenina", author: "Tolstoi"),
        Book(title: "To Kill a Mockingbird", author: "Harper Lee"),
        Book(title: "The Great Gatsby", author: "F. Scott Fitzgerald"),
        Book(title: "One Hundred Years of Solitude", author: "Gabriel García Márquez "),
        Book(title: "Mrs. Dalloway", author: "Virginia Woolf’"),
        Book(title: "Jane Eyre", author: "Charlotte Brontë’"),
    ]
    
    @State private var selected: Book? = nil // selection has to be an optional of the Type you use in the ForEach, here Book?
    
    var gridItems: [GridItem] {
        [GridItem(.adaptive(minimum: 180, maximum: 180))]
    }
    
    var body: some View {
        
        ScrollView (showsIndicators: false) {
            LazyVGrid(columns: gridItems) {
                ForEach(books) { item in   // you cant ForEach over one book, it has to be an array of books = [Book]
                    
                    Button(action: {
                        selected = item
                    }) {
                        BookTileModel(book: item)
                    }
                }
            }
        }.sheet(item: $selected) { item in
            BookSheetView(book: item)  // now that selected is of Type Book, this should work
        }
    }
}
Другие вопросы по тегам