与 JSON 挂钩的文本字段验证

问题描述 投票:0回答:1

我正在努力寻找一种逻辑方法来验证文本字段。我已成功解码 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": ""
        }
    ]

swiftui
1个回答
0
投票

使用您的原始代码尝试此方法,并带有可选的

.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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.