Learn Courses My Dashboard

Swift Foundations UI: Mod 5, lesson 4 preview problem

As I continue to work on Mod 5, I find Xcode does not work as expected. In the Mod, we are building an app to allow the user to access lessons and tests for those lessons. All we have done so far is set up two views. The HOME VIEW ROW has a set up for displaying a card in the HOME VIEW.

The problem comes when I try to preview the HomeView. The cards do not appear at all. So here are the my code and Chris’ code for both views, as well as the screen shots showing how the views should look.

Here are the codes for HomeViewRow.
Mine:
import SwiftUI

struct HomeViewRow: View {

var image: String
var title: String
var description: String
var count: String
var time: String

var body: some View {
    ZStack{
        Rectangle()
                    .foregroundColor(.white)
                    .cornerRadius(25, antialiased: true)
                    .aspectRatio(CGSize(width: 335, height: 175), contentMode: .fit)
                    .shadow(radius: 10)

        //learning card
        HStack {
            //Image
            Spacer()
            Image(image)
                .resizable()
                .frame(width: 116, height: 116)
                .clipShape(Circle())
            Spacer()
           //text
            VStack(alignment: .leading) {
                //headline
               Spacer()
                Text(title)
                    .bold()
                    .font(.title)
                    .padding(.bottom, 5)
                //description
                Text(description)
                    .bold()
                    .font(.headline)
                Spacer()
                //icons
                HStack(spacing: 10){
                // # of lessons/questions
                    Image(systemName: "text.book.closed")
                        .frame(width: 15, height: 15)
                    Text(count)
                        .bold()
                        .font(.caption)
                // time
                    Image(systemName: "clock")
                        .frame(width: 15, height: 15)
                    Text(time)
                        .bold()
                        .font(.caption)
                    
                }
                Spacer()
        }
            .aspectRatio(CGSize(width: 200,
                                height: 175), contentMode: .fit)
            Spacer()
    }
        .padding(.horizontal, 20)
   
    }
}

}

struct HomeRowView_Previews: PreviewProvider {
static var previews: some View {
HomeViewRow(image: “swift”, title: “Learn Swift”, description: “some description”, count: “10 Lessons”, time: “2 Hours”)
}
}

Chris’:

import SwiftUI

struct HomeViewRow: View {

var image: String
var title: String
var description: String
var count: String
var time: String

var body: some View {
    
    ZStack {
        
        Rectangle()
            .foregroundColor(.white)
            .cornerRadius(10)
            .shadow(radius: 5)
            .aspectRatio(CGSize(width: 335, height: 175), contentMode: .fit)
            
        
        HStack {
            
            // Image
            Image(image)
                .resizable()
                .frame(width: 116, height: 116)
                .clipShape(Circle())
            
            Spacer()
            
            // Text
            VStack (alignment: .leading, spacing: 10) {
                
                // Headline
                Text(title)
                    .bold()
                
                // Description
                Text(description)
                    .padding(.bottom, 20)
                    .font(.caption)
                
                // Icons
                HStack {
                    
                    // Number of lessons/questions
                    Image(systemName: "text.book.closed")
                        .resizable()
                        .frame(width: 15, height: 15)
                    Text(count)
                        .font(Font.system(size: 10))
                    
                    Spacer()
                    
                    // Time
                    Image(systemName: "clock")
                        .resizable()
                        .frame(width: 15, height: 15)
                    Text(time)
                        .font(Font.system(size: 10))
                    
                }
            }
            .padding(.leading, 20)
        }
        .padding(.horizontal, 20)
        
    }
    
    
}

}

struct HomeViewRow_Previews: PreviewProvider {
static var previews: some View {
HomeViewRow(image: “swift”, title: “Learn Swift”, description: “some description”, count: “10 Lessons”, time: “2 Hours”)
}
}

and codes for HomeView:
Mine:
import SwiftUI

struct HomeView: View {

@EnvironmentObject var model: ContentModel

var body: some View {
    
    NavigationView {
        VStack (alignment: .leading) {
            Text("What do you want to do today?")
                .padding(.leading, 20)
            
            ScrollView {
                
                LazyVStack {
                    
                    ForEach(model.modules) { module in
                        
                        VStack (alignment: .leading, spacing: 20) {
                            // Learning Card
                            HomeViewRow(image: module.content.image, title: "Learn \(module.category)", description: module.content.description, count: "\(module.content.lessons.count) Lessons", time: module.content.time)
                            
                            
                            // Test Card
                            HomeViewRow(image: module.test.image, title: "\(module.category) Test", description: module.test.description, count: "\(module.test.questions.count) Questions", time: module.test.time)
                        }
                    }
                    
                }
                .padding()
                
            }
        }
        .navigationTitle("Get Started")
    }
}

}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
HomeView().environmentObject(ContentModel())
}
}

Chris’:

import SwiftUI

struct HomeView: View {

@EnvironmentObject var model: ContentModel

var body: some View {
    
    NavigationView {
        VStack (alignment: .leading) {
            Text("What do you want to do today?")
                .padding(.leading, 20)
            
            ScrollView {
                
                LazyVStack {
                    
                    ForEach(model.modules) { module in
                        
                        VStack (spacing: 20) {
                            // Learning Card
                            HomeViewRow(image: module.content.image, title: "Learn \(module.category)", description: module.content.description, count: "\(module.content.lessons.count) Lessons", time: module.content.time)
                            
                            
                            // Test Card
                            HomeViewRow(image: module.test.image, title: "\(module.category) Test", description: module.test.description, count: "\(module.test.questions.count) Lessons", time: module.test.time)
                        }
                    }
                    
                }
                .padding()
                
            }
        }
        .navigationTitle("Get Started")
    }
}

}

struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
.environmentObject(ContentModel())
}
}
ans Screenshots:

I find the preview to be very hit or miss. I would say your best bet is if you run in the simulator and it works then you should be good to go.

I tried your code out and was able to see it in the preview.

What does your ContentModel look like?

Lowgy, unfortunately the simulator looks the same as the preview; see screenshot.

Hi, Rooster, this is the content view code.

mport Foundation

class ContentModel: ObservableObject {

@Published var modules = [Module]()

var styleData: Data?

init() {
   
    func getLocalData() {
        
        // Get a url to the json file
        let jsonUrl = Bundle.main.url(forResource: "data", withExtension: "json")
        
        do {
            // Read the file into a data object
            let jsonData = try Data(contentsOf: jsonUrl!)
            
            // Try to decode the json into an array of modules
            let jsonDecoder = JSONDecoder()
            let modules = try jsonDecoder.decode([Module].self, from: jsonData)
            
            // Assign parsed modules to modules property
            self.modules = modules
        }
        catch {
            // TODO log error
            print("Couldn't parse local data")
        }
    }
    // Parse the style data
    let styleUrl = Bundle.main.url(forResource: "style", withExtension: "html")
    do {
        // Read the file into a data object
        let styleData = try Data(contentsOf: styleUrl!)
        self.styleData = styleData
    }
    catch {
        // Log error
        print("Couldn't parse style data")
    }
}

}

Check the initializer of your ContentModel again. It doesn’t look right to me. For one thing, you have the getLocalData() function inside the init where it never actually gets called.

Yeah I believe rooster is right. You would want to define your getLocalData method outside of the init and then just have a simple call within the init.

    init() {
        getLocalData()   
    }

   func getLocalData(){
       //JSON Parsing Code here.  
   }

Yes, Rooster, that was it. Thank you so much for taking the time to look at the issue. Sometimes, I just can’t see a problem when it’s strange me in the face! I truly appreciate your help.

Lowgy, you and Rooster were right. The problem is now fixed. Thanks for taking the time to look at this. I truly appreciate your help. This community has such nice people who are so generous with their time.