Лист от 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
}
}
}