I am loading some data from a json file. I am trying to load the next set of data when a button is pressed however I can't seem to figure out how to add an action to the button that will load the next set of data when the button is pressed. Ideally, it would be nice to load the next set of data by the index (_id
)
Currently, as the code is written, only the first set of data will load. However, I am not sure how to load the next set of data
LabelData
import Foundation
struct LabelData: Codable {
var _id: Int
var _name: String
var _type: String
var _description: String
var label: String
}
ContentView
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
HStack {
Button(action: {
print("Red Action")
}) {
Text("R")
.frame(width: 100, height: 100)
.foregroundColor(Color.black)
.background(Color.red)
.clipShape(Circle())
}
}
VStack{
if let test = labels.first {
VStack {
Text(test._name)
}
VStack {
Text(test._type)
}
VStack {
Text(test._type)
}
}
}
.offset(x: 0, y: -100)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
DataLoader
import Foundation
var labels: [LabelData] = load("labeldata.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
labeldata
[
{
"_id" : 1,
"_name" : "Label1",
"_type" : "type1",
"_description" : "description1",
"label" : ""
},
{
"_id" : 2,
"_name" : "Label2",
"_type" : "type2",
"_description" : "description2",
"label" : ""
}
]
CodePudding user response:
try something like this approach to iterate through the array of LabelData
:
struct LabelData: Codable {
var _id: Int
var _name: String
var _type: String
var _description: String
var label: String
}
struct ContentView: View {
@State var labels: [LabelData] = []
// for testing
// [
// LabelData(_id: 0, _name: "name1", _type: "type1", _description: "description1", label: "www"),
// LabelData(_id: 1, _name: "name2", _type: "type2", _description: "description2", label: "zz"),
// LabelData(_id: 2, _name: "name3", _type: "type3", _description: "description3", label: "xx")
// ]
// index into the labels array
@State var index = 0
var body: some View {
HStack {
Button(action: { index = 1 }) {
if index < labels.count {
VStack {
Text(labels[index]._name)
Text(labels[index]._type)
Text(labels[index]._description)
}
} else {
Text("R")
}
}
.frame(width: 100, height: 100)
.foregroundColor(Color.black)
.background(Color.red)
.clipShape(Circle())
}
.onAppear {
labels = load("TestFile")
}
}
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
}