admin管理员组

文章数量:1356283

I am very new with swift. I have finished a course and I am trying to practice what I have learned making a small proyect.

I have a scrollview with a lazyVgrid to get some books from an api.

I am trying to have sections to get as a header of each section the name of the month, and in each section, the books that are released that month.

I have made a computed property with a function to get the date from the string (the date comes as a string in the json file). That property is called PublishedDateAsADate

I have made a foreach for each section and another one for the books, with a filter to show in that section just the books released that month... but it does not work.

It says:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

If I take the filter out, it works, but I have all the books in each section... (as shown in the screenshot)

What am I doing wrong? What can I do to improve that code???

import SwiftData
import SwiftUI

struct MediumGridLayout: View {
    @Environment(\.modelContext) var modelContext

    var books: [Book]

    var book: Book

    private var PublishedDate: String { book.volumeInfo.publishedDate ?? "N/A"}

    private var PublishedDateAsADate: Date { dateStringToDate(dateString: PublishedDate) ?? Date.now}

    private let calendar = Calendar.current

    //to animate the transition
    @Namespace private var namespace

    var columns = [
        GridItem (.adaptive(minimum: 110),  alignment: .top)
    ]

    var body: some View {

            ScrollView {
                LazyVGrid(columns: columns, spacing: 10) {

                    ForEach(1...12, id: \.self) { month in
                        Section {
                            ForEach(books.filter({
                                calendarponent(.month, from: $0.publishedDateAsADate) == month })) { book in

                                if  book.volumeInfo.imageLinks?.smallThumbnail == nil {
                                    HStack {
                                        NoPreviewView()
                                            .clipShape(.rect(cornerRadius: 15))
                                            .font(.system(size: 15))
                                            .frame(width: 70, height: 120)

                                        VStack (alignment: .leading){
                                            Text (book.volumeInfo.title)
                                                .font(.caption)
                                                .bold()
                                                .lineLimit(2)

                                            Text (book.volumeInfo.authors?.joined(separator: ", ") ?? "")
                                                .font(.caption2).foregroundStyle(.secondary)
                                        }

                                    }
                                } else {
                                    NavigationLink {
                                        BookView(book: book)

                                    } label: {
                                        AsyncCachedImage(url: URL(string: book.volumeInfo.imageLinks!.smallThumbnail!)!) { image in
                                            image
                                                .resizable()
                                                .scaledToFit()
                                                .clipShape(.rect(cornerRadius: 15))
                                        } placeholder: {
                                            ProgressView()
                                        }

                                    }
                                }

                            }
                        }

                        header: {
                            HStack {
                                Text("Available: \(calendar.monthSymbols[month-1])")
                                    .font(.title)
                                Spacer()
                            }
                        }
                    }

                }
                .buttonStyle(.plain)
            }

        .padding(.horizontal)
        .scrollBounceBehavior(.basedOnSize)

    }

    func dateStringToDate(dateString: String) -> Date? {
            let formats = ["yyyy-M-d", "yyyy-M", "yyyy-MM-d", "yyyy-MM", "yyyy-MM-dd", "yyyy"]
            let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale.autoupdatingCurrent
        dateFormatter.timeZone = TimeZone.current
            for format in formats {
                dateFormatter.dateFormat = format
                if let date = dateFormatter.date(from: dateString) {
                    return date
                }
            }
            return nil
        }
}

#Preview {
    MediumGridLayout(books: [SampleBook().sampleBook, SampleBook().sampleBook2, SampleBook().sampleBook, SampleBook().sampleBook2], book: SampleBook().sampleBook)
        .modelContainer(for: Book.self)
}

And also... I have to add var book: Book property to use it in my publishedDate, haven't I ???? Just with var books: [Book] I can't get the publishedDate property, can I ?????????

I have seen this post, but I can't make my code work...

How do I separate events into different sections of a list based on a date in SwiftUI?

This is what I get with no "filter". I have all months but in each one I have all the books, not separated by the month they are released which is what I want...

本文标签: