I have the following view:
//
// RandomMinifig.swift
// MinifiguresV4
//
// Created by Nicolò Campagnoli on 19/12/22.
//
import SwiftUI
struct RandomMinifig: View {
let minifigs: [Minifig] = Bundle.main.decode("minifigures.json")
var body: some View {
var random = Int.random(in: 1...minifigs.count)
let minifig = minifigs[random]
NavigationView {
VStack {
Image("Series\(minifig.id)")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 250, height: 250)
Text("\(minifig.name)")
.font(.headline)
Text("\(minifig.series) • \(minifig.number)")
Text("\(String(format: "%.2f", minifig.price))€")
.foregroundColor(.gray)
}
.navigationTitle("Random minifigure")
}
}
}
struct RandomMinifig_Previews: PreviewProvider {
static var previews: some View {
RandomMinifig()
}
}
That creates a simple view with a random object with an image in the middle on the screen
I tried to add a button or a text with the option .onTapGesture, and also added a .refreshable option in the navigation view, both re-givining a value to 'random'. but this option didn't reload the full page. My goal was a simple button to press, that generates an other random number, that displays an other object
CodePudding user response:
Hi you must use @State property wrapper the UI/Model combined changes. Here there's your file corrected(I've also changed the Json decode process to the right one.
import SwiftUI
struct RandomMinifig: View {
let minifigs: [Minifig] = {
guard let filePath = Bundle.main.path(forResource: "data", ofType: "json") else {print("file path") ; return []}
guard let fileContent = try? String(contentsOfFile: filePath).data(using: .utf8) else {print("file content") ;return []}
guard let minifigs = try? JSONDecoder().decode([Minifig].self, from: fileContent) else {print("decode problem") ;return []}
return minifigs
}()
var random: Int {
guard minifigs.count > 0 else {return 0}
return Int.random(in: 0...minifigs.count - 1) // If the json file is empty throw an error because it tries to take a number in an invalid range(0 ... - 1)
}
@State var currentMinifig: Minifig = Minifig(id: "", name: "", series: "", number: 0, price: 0)
var body: some View {
NavigationView {
VStack {
Image("Series\(currentMinifig.id)")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 250, height: 250)
Text("\(currentMinifig.name)")
.font(.headline)
Text("\(currentMinifig.series) • \(currentMinifig.number)")
Text("\(String(format: "%.2f", currentMinifig.price))€")
.foregroundColor(.gray)
Button("Reload") {
currentMinifig = minifigs[random]
}
}
.navigationTitle("Random minifigure")
.onAppear {
guard minifigs.count > 0 else {currentMinifig = Minifig(id: "", name: "", series: "", number: 0, price: 0); return}
currentMinifig = minifigs[random]
}
}
}
}
struct Minifig: Codable {
var id: String
var name: String
var series: String
var number: Int
var price: Double
}
Sorry for the bad indentation but I don't understand so well how Stack Overflows works.
Here there the json files that I used as model
[
{
"name" : "ted",
"id" : "1",
"series" : "0",
"number" : 0,
"price" : 10
},
{
"name" : "steve",
"id" : "2",
"series" : "0",
"number" : 2,
"price" : 20
}
]