Learn Courses My Dashboard

Module 2 lesson 13 and 15

I am following Chris’s Lesson 15 and have come across this error which does not allow mw to do the preview.


There is obviously something wrong with the code in RecipeDetailView.

Can you copy the code from the RecipeDetailView and paste it in a reply as text.

Place 3 back-ticks ``` on the line above your code and 3 back-ticks ``` on the line below your code so that it is formatted nicely in the reply. The back-tick character is located on the same keyboard key as the tilde character ~ (below the Esc key).

This also makes it easier for anyone assisting as they can copy the code and carry out some testing.

For your own benefit it seems that the indenting that should apply to the lines of code do not look right. You can fix that by selecting all your code (Command + A) and then press Control + i to re-indent your code. This will make it much easier to identify missing curly braces and also enable you to see the structure much easier.

Thanks Chris, Hope this is OK
strong text//
// RecipeDetailView.swift
// Recipe List App1
//
// Created by Jaime Fernandes on 28/9/21.
//

import SwiftUI

struct RecipeDetailView: View {
    
    var recipe:Recipe
    
    var body: some View {
        
        ScrollView {
            
            VStack (alignment: .leading) {
                
                // MARK: Recipe Image
                Image(recipe.image)
                    .resizable()
                    .scaledToFit()
                
                // MARK: Ingredients
                VStack(alignment: .leading) {
                    Text("Ingredients")
                        .font(.headline)
                        .padding(.bottom, 5)
                    
                    ForEach (recipe.ingredients, id:\.self) { item in
                        Text("•" + item)
                    }
                }
                
                // MARK: Directions
                VStack(alignment: .leading) {
                    Text("Directions")
                        .font(.headline)
                        .padding(.bottom, 5)
                    
                    ForEach(recipe.directions, id: \.self) { index in
                        Text(String(index+1) + "." + recipe.directions[index])
                            .padding(.bottom, 5)
                        
                    }
                }
            }
        }
    }
}
struct RecipeDetailView_Previews: PreviewProvider {
    static var previews: some View {
        
        //Create a dummy recipe and pass it on into the detail view so that we can see a preview
        let model = RecipeModel()
        
        RecipeDetailView(recipe: model.recipes[0])
    }
}

Hi @Jaime

The issue was with the recipe.directions ForEach(). In order to get an index you need to write the ForEach like this:

ForEach(0..<recipe.directions.count id: \.self) { index in
    Text(........
}

That generates an integer index which means that the overall struct needs to look like this:

struct RecipeDetailView: View {

    var recipe:Recipe

    var body: some View {

        ScrollView {

        VStack (alignment: .leading) {

            // MARK: Recipe Image
            Image(recipe.image)
                .resizable()
                .scaledToFit()

                // MARK: Ingredients
                VStack(alignment: .leading) {
                    Text("Ingredients")
                        .font(.headline)
                        .padding(.bottom, 5)

                    ForEach (recipe.ingredients, id:\.self) { item in
                        Text("•" + item)
                    }
                }

                // MARK: Directions
                VStack(alignment: .leading) {
                    Text("Directions")
                        .font(.headline)
                        .padding(.bottom, 5)

                    ForEach(0..<recipe.directions.count, id: \.self) { index in
                        Text(String(index + 1) + "." + recipe.directions[index])
                            .padding(.bottom, 5)
                            .fixedSize(horizontal: false, vertical: true)
                    }
                }
            }
        }
    }
}

You will see that I also added another modifier that you may not have encountered and that is:

.fixedSize(horizontal: false, vertical: true)

What that does is prevent each of the directions instructions sentence from being truncated.

Thanks once again Chris, My mantra should be practice, practice, practice.

Hello, I have added 1 asset to lesson 15 but it the List view crashes. I have attached RecipeListView and Recipe Detail View as required. Have spent a great deal of time understanding these projects.However…
//```
// ContentView.swift
// Recipe List App
//
// Created by Jaime Fernandes on 11/9/21.
//

//
// ContentView.swift
// Recipe List App1
//
// Created by Jaime Fernandes on 24/9/21.

import SwiftUI

struct RecipeListView: View {

//Reference the view model
@ObservedObject var model = RecipeModel()
var body: some View {
    
    NavigationView {
        List(model.recipes) { r in
            
            NavigationLink(
                destination: RecipeDetailView(recipe:r),
                label: {
                    // MARK: Row
                    
                    HStack(spacing:20.0) {
                        Image(r.image)
                            .resizable()
                            .scaledToFill()
                            .frame(width: 50, height: 50, alignment:.center)
                            .clipped()
                            .cornerRadius(5)
                        Text(r.name)
                        
                        
                    }
                })
        }
        .navigationBarTitle("All Recipes")
        
    }
}

}
struct RecipeListView_Previews: PreviewProvider {
static var previews: some View {
RecipeListView()
}
}

//
// RecipeDetailView.swift
// Recipe List App1
//
// Created by Jaime Fernandes on 28/9/21.
//

import SwiftUI

struct RecipeDetailView: View {

var recipe:Recipe

var body: some View {
    
    ScrollView {
        
        VStack (alignment: .leading) {
            
            // MARK: Recipe Image
            Image(recipe.image)
                .resizable()
                .scaledToFit()
            
            // MARK: Ingredients
            VStack(alignment: .leading) {
                Text("Ingredients")
                    .font(.headline)
                    .padding([.bottom, .top], 5)
                
                ForEach (recipe.ingredients, id:\.self) { item in
                    Text("•" + item)
                }
            }
            .padding(.horizontal)
            // MARK: Divider
            
            Divider()
            // MARK: Directions
            VStack(alignment: .leading) {
                Text("Directions")
                    .font(.headline)
                    .padding(.bottom, 5)
                
                ForEach(0..<recipe.directions.count, id: \.self) { index in
                    Text(String(index+1) + "." + recipe.directions[index])
                        .padding(.bottom, 5)
                        .fixedSize(horizontal: false, vertical: true)
                    
                }
            }
            .padding(.horizontal)
        }
    }
    .navigationBarTitle(recipe.name)
}

}
struct RecipeDetailView_Previews: PreviewProvider {
static var previews: some View {

    //Create a dummy recipe and pass it on into the detail view so that we can see a preview
    let model = RecipeModel()
    
    RecipeDetailView(recipe: model.recipes[0])
}

}