我正在努力寻找一种逻辑方法来验证文本字段。我已成功解码 JSON 并显示,但我想让用户输入答案,然后将其与 JSON 中针对该特定问题的所有可能“答案”进行比较,如果经过验证,可能会添加一个绿色 V 形。
我也设法将 TextField 挂接到“问题”,但如何捕获用户输入并与“答案”部分进行比较?我知道 .onSubmit 和 .onAppear 修饰符,但我不知道该怎么做。
有什么建议,谢谢
// CONTENT VIEW
import SwiftUI
struct ContentView: View {
var item: [Exercises] = Bundle.main.decode("random.json")
@State private var items1: [Exercises] = []
@State private var isMatched = false
var body: some View {
NavigationStack {
List($items1) { $item in
Text(item.question)
TextField("Tap to create", text: $item.text)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
}
.navigationTitle("Variables")
}
Button(action: {
addItem()
}, label: {
Text("Button")
})
}
private func addItem() {
guard let newItem = item.randomElement() else {return}
withAnimation {
items1.insert(newItem, at: 0)
}
}
}
#Preview {
ContentView()
}
// MODEL
import Foundation
struct Exercises: Codable, Identifiable, Hashable {
let id: Int
let question: String
var answer: [String]
var text: String
}
extension Bundle {
func decode<T: Codable>(_ file: String) -> T {
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Could not find \(file) in bundle.")
}
guard let data = try? Data(contentsOf: url) else {
fatalError("Could not load \(file) from bundle.")
}
let decoder = JSONDecoder()
guard let loadedData = try? decoder.decode(T.self, from: data) else {
fatalError("Could not decode \(file) from bundle.")
}
return loadedData
}
}
// JSON
[
{
"id": 1,
"question": "Create a variable called \"greeting\" and assign the value: Hello",
"answer": ["var greeting = \"Hello\"","var greeting = \"hello\""],
"text": ""
},
{
"id": 2,
"question": "Create a variable called \"person\" and assign the value: John",
"answer": ["var person = \"John\"","var person = \"john\""],
"text": ""
},
{
"id": 3,
"question": "Create a variable called \"city\" and assign the value: London",
"answer": ["var city = \"London\"","var city = \"london\""],
"text": ""
},
{
"id": 4,
"question": "Create a variable called \"food\" and assign the value: kebab",
"answer": ["var food = \"Kebab\"","var food = \"kebab\""],
"text": ""
},
{
"id": 5,
"question": "Create a variable called \"country\" and assign the value: United Kingdom",
"answer": ["var country = \"United Kingdom\"","var country = \"united kingdom\""],
"text": ""
},
{
"id": 6,
"question": "Create a constant called \"car\" and assign the value: orange",
"answer": ["let car = \"orange\"","let car = \"Orange\""],
"text": ""
},
{
"id": 7,
"question": "Create a constant called \"laptop\" and assign the value: MacBook",
"answer": ["let laptop = \"macbook\"","let laptop = \"Macbook\""],
"text": ""
},
{
"id": 8,
"question": "Create a constant called \"planet\" and assign the value: Mars",
"answer": ["let planet = \"mars\"","let planet = \"Mars\""],
"text": ""
},
{
"id": 9,
"question": "Create a constant called \"type\" and assign the value: electric",
"answer": ["let type = \"electric\"","let type = \"Electric\""],
"text": ""
},
{
"id": 10,
"question": "Create a constant called \"color\" and assign the value: green",
"answer": ["let color = \"green\"","let color = \"Green\""],
"text": ""
},
{
"id": 11,
"question": "Create a variable of type int called \"house\" and assign the value: 5",
"answer": ["var house = 5"],
"text": ""
},
{
"id": 12,
"question": "Create a variable of type int called \"doors\" and assign the value: 2",
"answer": ["var doors: Int = 2"],
"text": ""
},
{
"id": 13,
"question": "Create a constant of type int called \"windows\" and assign the value: 10",
"answer": ["let windows: Int = 10"],
"text": ""
},
{
"id": 14,
"question": "Create a constant of type int called \"wheels\" and assign the value: 4",
"answer": ["let wheels: Int = 4"],
"text": ""
}
]
使用您的原始代码尝试此方法,并带有可选的
.onSubmit
和一个小
Exercise
模型中的函数。注意我更改了一些名称以更好地反映
属性的含义,例如有或没有 s
struct ContentView: View {
var items: [Exercise] = Bundle.main.decode("random.json")
@State private var items1: [Exercise] = []
@State private var isMatched = false
var body: some View {
NavigationStack {
List($items1) { $item in
Text(item.question)
TextField("Tap to create", text: $item.text)
.border(item.isCorrectAnswer() ? .green : .red) // <-- for testing
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
// --- here
.onSubmit {
let isCorrectAnswer = item.isCorrectAnswer()
print("-----> isCorrectAnswer: \(isCorrectAnswer) ")
}
}
.navigationTitle("Variables")
}
Button(action: {
addItem()
}, label: {
Text("Button")
})
}
private func addItem() {
guard let newItem = items.randomElement() else {return}
withAnimation {
items1.insert(newItem, at: 0)
}
}
}
struct Exercise: Codable, Identifiable, Hashable { // <--- here
let id: Int
let question: String
var answer: [String]
var text: String
// --- here
func isCorrectAnswer() -> Bool {
let txt = text.trimmingCharacters(in: .whitespacesAndNewlines)
let isCorrect = answer.contains(where: {
$0.replacingOccurrences(of: "\"", with: "") == txt
})
return isCorrect
}
}