将更新的数组数据传递给 uipickerview

Posted

技术标签:

【中文标题】将更新的数组数据传递给 uipickerview【英文标题】:Passing updated array data to uipickerview 【发布时间】:2019-11-21 02:26:04 【问题描述】:

对于 swift 来说还是个新手,我在将更新的数据传递到 pickerview 时遇到了一些麻烦。我收到“索引超出范围”错误。我怀疑 uipickerview 看到的是空数组,即使数组正在更新。非常感谢任何帮助。

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource 

    @IBOutlet weak var nameDisplay: UILabel!
    @IBOutlet weak var ageDisplay: UILabel!
    @IBOutlet weak var emailDisplay: UILabel!
    @IBOutlet weak var pickerView: UIPickerView!



    @IBOutlet weak var txtfirstName: UITextField!
    @IBOutlet weak var txtAge: UITextField!
    @IBOutlet weak var txtEmail: UITextField!
    @IBOutlet weak var lblValidationMessage: UILabel!

    var ages = [Int]()
    var emailAddresses = [String]()
    var firstNames = [String]()

    override func viewDidLoad() 
        super.viewDidLoad()
        //     lblValidationMessage.isHidden = true
        // Do any additional setup after loading the view.

        //links txtAge to the UITextField class, which gives access to func textfield
        txtAge?.delegate = self
        pickerView?.dataSource = self
        pickerView?.delegate = self
    

    // restricts the values possible to input in txtAge.text

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 

        let allowedCharacters = "1234567890"
        let allowedCharcterSet = CharacterSet(charactersIn: allowedCharacters)
        let typedCharcterSet = CharacterSet(charactersIn: string)
        return allowedCharcterSet.isSuperset(of: typedCharcterSet)
    

    @IBAction func addUserButton(_ sender: UIButton) 

        //validation of data in the text boxes

        lblValidationMessage.isHidden = true
        if let firstName = txtfirstName.text, firstName == "" 
            lblValidationMessage.isHidden = false
            lblValidationMessage.text = "Enter Your Name"
            return
        

        if let age = txtAge.text, age == "" 
            lblValidationMessage.isHidden = false
            lblValidationMessage.text = "Please enter a numerical age"
            return
        

        if let email = txtEmail.text, email.isEmpty 
            lblValidationMessage.isHidden = false
            lblValidationMessage.text = "Please enter an email address"
            return
        


        //MARK: Adds entries to the 3 arrays

        firstNames.append(txtfirstName.text!)

        //Converts string to int, the age array requires INT
        let age:Int! = Int(txtAge.text!)
        ages.append(age)

        emailAddresses.append(txtEmail.text!)



        txtfirstName.text = ""
        txtAge.text = ""
        txtEmail.text = ""

        //Brings focus back to First Name text field
        txtfirstName.becomeFirstResponder()
    

    func numberOfComponents(in pickerView: UIPickerView) -> Int 
        return 1
    

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        return firstNames.count
    

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        nameDisplay.text = firstNames[row]
    

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        return firstNames[row]
    



【问题讨论】:

什么时候崩溃?当VC第一次出现时,或者当你按下“addUser”按钮时?你在任何地方打电话给reloadAllComponents()(或reloadComponent() 字段填充在第一个 vc 中,addUser 更新数组,我选择包含 pickerview 的 vc,它显示一个空的选择器,然后它因“索引超出范围”而崩溃。当我硬编码 firstnames 数组的内容时,pickerview 被正确填充。 【参考方案1】:

更改数据后尝试拨打reloadAllComponents()

【讨论】:

感谢您的回复,我尝试添加 pickerView.reloadAllComponents () 现在我得到“线程 1:致命错误:在隐式展开可选值时意外发现 nil。”我是否正确更新了我的阵列?似乎pickviewView 没有看到附加的项目,或者数据没有刷新。我也在各个地方尝试过 reloadAllComponenets,但仍然没有运气。 我将数组声明更改为静态变量,现在它可以工作了。【参考方案2】:

它看起来正在使用静态 var 声明来更新数组,我不确定它在编程上是否正确。我确实认为结构会是一种更好的方法。无论如何,感谢您对下一个错误的帮助!

//  ViewController.swift

导入 UIKit

类 ViewController: UIViewController, UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource

@IBOutlet weak var nameDisplay: UILabel!
@IBOutlet weak var ageDisplay: UILabel!
@IBOutlet weak var emailDisplay: UILabel!
@IBOutlet weak var pickerView: UIPickerView!

@IBOutlet weak var txtfirstName: UITextField!
@IBOutlet weak var txtAge: UITextField!
@IBOutlet weak var txtEmail: UITextField!
@IBOutlet weak var lblValidationMessage: UILabel!

static var ages = [Int]()
static var emailAddresses = [String]()
static var firstNames = [String]()

override func viewDidLoad() 
    super.viewDidLoad()
    //     lblValidationMessage.isHidden = true
    // Do any additional setup after loading the view.

    txtAge?.delegate = self
    pickerView?.dataSource = self
    pickerView?.delegate = self


func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 

    let allowedCharacters = "1234567890"
    let allowedCharcterSet = CharacterSet(charactersIn: allowedCharacters)
    let typedCharcterSet = CharacterSet(charactersIn: string)
    return allowedCharcterSet.isSuperset(of: typedCharcterSet)


@IBAction func addUserButton(_ sender: UIButton) 

    lblValidationMessage.isHidden = true
    if let firstName = txtfirstName.text, firstName == "" 
        lblValidationMessage.isHidden = false
        lblValidationMessage.text = "Enter Your Name"
        return
    

    if let age = txtAge.text, age == "" 
        lblValidationMessage.isHidden = false
        lblValidationMessage.text = "Please enter a numerical age"
        return
    

    if let email = txtEmail.text, email.isEmpty 
        lblValidationMessage.isHidden = false
        lblValidationMessage.text = "Please enter an email address"
        return
    

    updateArray()



func updateArray()

    ViewController.firstNames.append(txtfirstName.text!)

    let age:Int! = Int(txtAge.text!)
    ViewController.ages.append(age)

    ViewController.emailAddresses.append(txtEmail.text!)

    txtfirstName.text = ""
    txtAge.text = ""
    txtEmail.text = ""

    txtfirstName.becomeFirstResponder()

    //Checks to see data is being added to the arrays
    print(ViewController.firstNames)
    print(ViewController.ages)
    print(ViewController.emailAddresses)


func numberOfComponents(in pickerView: UIPickerView) -> Int 
    return 1


func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 

    return ViewController.firstNames.count


func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
    return ViewController.firstNames[row]


func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    nameDisplay.text = ViewController.firstNames[row]

    let emailIndex: Int = row
    emailDisplay.text = ViewController.emailAddresses[emailIndex]

    let ageIndex: Int = row
    ageDisplay.text! = String(ViewController.ages[ageIndex])

【讨论】:

以上是关于将更新的数组数据传递给 uipickerview的主要内容,如果未能解决你的问题,请参考以下文章

如何通过数组将数据传递给表格视图?

在不同的 ViewController 之间将数据传递给数组

将数组数据传递给循环中的变量

如何将数组作为表单数据传递给 Postman

如何将更新的数据传递给已经渲染的子 vue 组件

将php变量/数组数据传递给角度js