首页 > 解决方案 > 获取 Button 和 Textfield 数据,当它们在 swift 5 中以编程方式添加时

问题描述

 我有一个动态表单,我在其中基于 json 响应创建文本字段和按钮。按钮和文本字段的数量可能会有所不同。当我点击按钮以显示带有选项列表(每个按钮的相应数据)的操作表或将数据放入文本字​​段时,我如何获取保存在其特定变量中的特定字段的数据?

 //Buttons
 func subViewButton(placeholder:String){
 let myFirstButton = UIButton()
            myFirstButton.setTitle(placeholder, for: .normal)
            myFirstButton.setTitleColor(.blue, for: .normal)
            myFirstButton.backgroundColor = UIColor.systemGray
            myFirstButton.frame = CGRect(x: 0, y: 0, width: 1, height: 40)
            myFirstButton.addTarget(self, action: #selector(pressed), for: .touchUpInside)
            formStackView.addArrangedSubview(myFirstButton)
            formStackView.translatesAutoresizingMaskIntoConstraints = false
 }
 @objc func pressed() {
    //action here for specific button press
}
 //Textfields
 func subviewTextField(placeholder:String){
    let tectfield = SkyFloatingLabelTextField(frame: CGRect(x: 0, y: 0, width: 1, height: 40))
    tectfield.placeholder = placeholder
    tectfield.font = UIFont.systemFont(ofSize: 15)
    tectfield.autocorrectionType = UITextAutocorrectionType.no
    tectfield.clearButtonMode = UITextField.ViewMode.whileEditing
    tectfield.contentVerticalAlignment = UIControl.ContentVerticalAlignment.center
    tectfield.delegate = self
    tectfield.translatesAutoresizingMaskIntoConstraints = false
    tectfield.selectedTitleColor = Utility.GlobalVariable.yellowColor
    tectfield.selectedLineColor = Utility.GlobalVariable.yellowColor
    tectfield.tintColor = Utility.GlobalVariable.blueColor
    formStackView.spacing = 8
    formStackView.addArrangedSubview(tectfield)
    formStackView.translatesAutoresizingMaskIntoConstraints = false
} 

我有一个 for 循环,在其中我根据一个键填充表单,其中定义它是按钮或文本字段。

标签: swiftdynamicuibuttonuitextfield

解决方案


当您使用 for 循环创建所有按钮时,您可以枚举它们以便获取数据字段的索引并将索引作为标签分配给每个按钮。

一旦您点击按钮,它将触发 IBAction,它将按钮本身作为参数(发送者)提供。然后,您现在可以从其标签中发现哪个按钮被点击,并使用后者来检索相关数据。

private let formFields = ["Name", "Age", "Gender"]

private func createButtonsFromDataArray() {
    for (index, formField) in formFields.enumerated() {
        let button = UIButton()
        // [...]
        button.tag = index
        button.addTarget(self, action: #selector(pressed(sender:)), for: .touchUpInside)
        // [...]
    }

}

@objc func pressed(sender: UIButton) {
    print("The associated data to the button is \(formFields[sender.tag])")
}

关于文本字段,您可以执行相同的操作,只是保留对您在数组中创建的所有文本字段的引用。通过这种方式,您将能够检索textField.text每个文本字段的信息,然后创建一个Encodable结构,您可以向该结构提供您希望通过上传/POST URLRequest 发布的不同信息。

private var formTextFields: [UITextField] = []

private func createTextFieldFromDataArray() {
    for (index, formField) in formFields.enumerated() {
        let textField = UITextField()
        // [...]
        textField.tag = index // probably not necessary as the position in the array would provide the index but... depends on which solution you want to go with
        formTextFields.append(textField)
        // [...]
    }

}

private func postFormData() {
    // here obviously you have multiple options
    // But let's say the form fields are not dynamic you can create a struct, if not you would have to encode to `[String:Any]` and reinterpret that on the backend.

    var dataToUpload: [String: Any] = []
    for (index, formField) in formFields.enumerated() {
        dataToUpload[formField] = formTextFields[index].text
    }


    let encoder = JSONEncoder()
    let data = encoder.encode(dataToUpload)

    // URLSession.shared. etc.

}

如果不是动态结构:


struct FormData: Encodable {
    let age: Int
    let name: String
    let gender: String
}

推荐阅读