swiftcore-dataswiftuiswiftui-listswiftui-previews

A custom View works, but its preview does not compile


For the question I have prepared a simple test project at Github:

List screenshot

It is a SwiftUI List with a custom View TopRow.swift:

struct TopRow: View {
    let top:TopEntity
    
    var body: some View {
        HStack {
            Circle()
                .frame(width: 60, height: 60)
            Spacer()
            Text(top.given ?? "Unknown Person")
                .frame(minWidth: 60, maxWidth: .infinity, alignment: .leading)
            Spacer()
            VStack {
                Text("Elo rating: \(top.elo)")
                Text("Average time: \(top.avg_time ?? "")")
                Text("Average score: \(String(top.avg_score))")
            }.fixedSize(horizontal: true, vertical: false)
        }.font(.footnote)
    }
}

As you have seen in the above screenshot it works ok.

However the preview of it does not work:

struct TopRow_Previews: PreviewProvider {
    static var topEntity = TopEntity(context: PersistenceController.preview.container.viewContext)
    topEntity.uid = 19265
    topEntity.elo = 2659
    topEntity.given = "Alex"
    topEntity.motto = "TODO"
    topEntity.photo = "https://slova.de/words/images/female_happy.png"
    topEntity.avg_score = 18.8
    topEntity.avg_time = "03:06"

    static var previews: some View {
        TopRow(top: topEntity)
            .padding()
            .previewLayout(.sizeThatFits)
    }
}

Xcode reports a syntax error Consecutive declarations on a line must be separated by ';'

Error message

What is happening there, please help me (a Swift newbie) to understand.

I have tried to put a semicolon there, but it did not really work.


Solution

  • You can't put imperative code like that at the top level of a struct or class -- the top level is reserved for declarations of functions and properties.

    You could make the topEntity a computed property instead -- that way your imperative assignments can go inside the { } and not exist at the top level:

    struct TopRow_Previews: PreviewProvider {
        static var topEntity : TopEntity {
            var topEntity = TopEntity(context: PersistenceController.preview.container.viewContext)
            topEntity.uid = 19265
            topEntity.elo = 2659
            topEntity.given = "Alex"
            topEntity.motto = "TODO"
            topEntity.photo = "https://slova.de/words/images/female_happy.png"
            topEntity.avg_score = 18.8
            topEntity.avg_time = "03:06"
            return topEntity
        }
    
        static var previews: some View {
            TopRow(top: topEntity)
                .padding()
                .previewLayout(.sizeThatFits)
        }
    }