Ios 从JSON加载信息

Ios 从JSON加载信息,ios,json,swift,Ios,Json,Swift,我的JSON文件中有三行(问题)。当应用程序启动时,我想从JSON加载信息。在title中,我想从question.number中的textlab.text中加载信息,我想从question.text中的showerlabel.text中加载信息,我想从question.ans中加载信息。当我在textField中写入问题的正确答案时,回答并按下键盘上的“完成”按钮,我想在控制台和我的设备中看到打印(“右”),我想看到下一个问题。但我有个问题。当应用程序启动时,我从JSON加载第一行({“num

我的JSON文件中有三行(问题)。当应用程序启动时,我想从JSON加载信息。在
title
中,我想从
question.number
中的
textlab.text
中加载信息,我想从
question.text
中的
showerlabel.text中加载信息,我想从
question.ans中加载信息。当我在
textField
中写入
问题的正确答案时,回答
并按下键盘上的“完成”按钮,我想在控制台和我的设备中看到
打印(“右”)
,我想看到下一个问题。但我有个问题。当应用程序启动时,我从JSON加载第一行(
{“number”:“1”,“text”:“1”,“answer”:“1”},
)。在我的
showAnswerLabel.text
answer=
1
中。但当我在
textField
中写入
1
并按下“完成”按钮时,我无法在控制台中获得
print(“right”)
。但如果我从JSON的第二行(
{“number”:“2”,“text”:“2”,“answer”:“2”},
)在
textField
中写入answer=
2
),然后按下“完成”按钮,我会在控制台中得到
打印(“右”)
。但正确答案应该是
showAnswerLabel.text中的数字,即
1
。如何修复它

我的新代码:

{
    "questions" : [{"number": "1", "text": "1", "answer": "1"},
                   {"number": "2", "text": "2", "answer": "2"},
                   {"number": "3", "text": "3", "answer": "3"}]
}

struct Root : Decodable {
    let questions : [Question]
}

struct Question : Decodable {
    let number, text, answer : String
}

class ViewController: UIViewController, UITextFieldDelegate {

var counter = 0
var questions = [Question]()
@IBOutlet var textLabel: UILabel!
@IBOutlet var showAnswerLabel: UILabel!
@IBOutlet weak var textField: UITextField!

override func viewDidLoad() {
        super.viewDidLoad()

        let url = Bundle.main.url(forResource: "0", withExtension: "json")!
        let data = try! Data(contentsOf: url)
        let result = try! JSONDecoder().decode(Root.self, from: data)
        self.questions = result.questions

        textField.delegate = self
        textField.returnKeyType = .done
        _ = textFieldShouldReturn(textField)

    }

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()

        let question = questions[counter]
        title = question.number
        textLabel.text = question.text
        showAnswerLabel.text = question.answer
        counter = (counter + 1) % questions.count

        if textField.text == question.answer {
            print("right")

        }

        return true
    }

textfield提取UI更新的可能修复程序应返回
,并绑定到
计数器的更改

class ViewController: UIViewController, UITextFieldDelegate 
{
    var questions = [Question]()
    @IBOutlet var textLabel: UILabel!
    @IBOutlet var showAnswerLabel: UILabel!
    @IBOutlet weak var textField: UITextField!

    var counter: Int = -1 {
       didSet {
           guard counter >= 0, counter < questions.count else { fatalError() }       
           let question = questions[counter] 
           updateUI(with: question)
       }
    }

    override func viewDidLoad() 
    {
        super.viewDidLoad()

        let url = Bundle.main.url(forResource: "0", withExtension: "json")!
        let data = try! Data(contentsOf: url)
        let result = try! JSONDecoder().decode(Root.self, from: data)
        self.questions = result.questions
        textField.delegate = self
        textField.returnKeyType = .done

        counter = 0 // will trigger `updateUI(with: questions[0])`
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()

        let question = questions[counter]        
        if textField.text == question.answer {
            print("right")
            // increment counter only answer is right
            // will trigger an UI update
            counter = (counter + 1) % questions.count 
        }

        return true
    }

    func updateUI(with question: Question) {
        title = question.number
        textLabel.text = question.text
        showAnswerLabel.text = question.answer
    }
}
类ViewController:UIViewController、UIExtFieldDelegate
{
变量问题=[问题]()
@IBOUTLE var textLabel:UILabel!
@IBOUTLE var showAnswerLabel:UILabel!
@IBOutlet弱var textField:UITextField!
变量计数器:Int=-1{
迪塞特{
守卫计数器>=0,计数器Bool{
textField.resignFirstResponder()辞职
让问题=问题[计数器]
如果textField.text==question.answer{
打印(“右”)
//增量计数器唯一的答案是正确的
//将触发UI更新
计数器=(计数器+1)%questions.count
}
返回真值
}
func updateUI(带问题:问题){
标题=问题.编号
text label.text=question.text
showAnswerLabel.text=question.answer
}
}

我不会像这样做,但你明白了。

计数器是什么?
,一个初始化为零的全局变量?@djromero更新的问题试着自己调试一下。在viewDidload上,为了设置UI,您第一次执行了代码。因此,您的
计数器
为1。当您按下“完成”时,您正在为第二个问题设置文本文件,并为第二个问题设置答案。为什么在
viewDidLoad
中调用
\=textfieldshouldlreturn(textField)
?正如@MichaelVorontsov所说的那样,这正在改变
计数器
并破坏您的逻辑。@djromero如果我不调用
\uuu=textField,则应返回(textField)
中的
viewDidLoad
应用程序启动时,我有空标签。我有一个问题:
条件绑定的初始值设定项必须具有可选类型,不是“问题”
我修复了故障。现在试试。您可能需要修复其他一些问题,这只是关于如何继续的一个想法,而不是作为您的最终代码。谢谢!这是工作。我删除了这一行
counter=(counter+1)%questions.count
if textField.text==question.answer
中删除,并在该检查下添加
if textField.text==question.answer
,因为我想显示下一个问题,如果答案也是错误的。我有一个小问题。我需要用户在应用程序启动后查看JSON中的第一个问题。在用户回答问题后(按键盘上的“完成”按钮),他应该会看到JSON等的下一个问题。什么是最好的方法?也许我目前的代码根本不适合这个任务?如何选择最合适的代码?当您修改
计数器时,UI将更新。在我的示例中,我更改了
计数器
,只有在答案正确时,如果您需要,您可以随时更改它。