多个文本字段的 PickerView 只显示一个数组

Posted

技术标签:

【中文标题】多个文本字段的 PickerView 只显示一个数组【英文标题】:PickerView for multiple text fields is just showing one Array 【发布时间】:2020-03-02 13:17:57 【问题描述】:

我有一个奇怪的问题,但我想你们可以很容易地告诉我这个错误。我正在为多个文本字段使用选择器视图。但它只显示每个文本字段的“最后一个数组”,并将最后一个文本字段中所选行的所有内容推到顶部。 因此,似乎每个文本字段只控制最后一个文本字段。

这里是涉及的代码,希望你们能帮助我:

class SignUpViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource 




    //Mark: Properties


    @IBOutlet weak var genderPicker: UITextField!
    @IBOutlet weak var branchePicker: UITextField!
    @IBOutlet weak var countryPicker: UITextField!




    // Picker View Arrays
    let genders = ["male", "female", "non-binary"]
    let branches = ["Advertising", "Architecture", "Design: Product", "Design: Graphic", "Design: Fashion", "Design: Others", "Film/ Video & TV", "IT", "Museums & Galleries", "Music", "Photography", "Performing & Visual Arts", "Radio", "Others"]
    let countries = ["Austria", "Australia", "USA", "Germany"]

    // Picker View
    var pickerViewSignUp = UIPickerView()



    override func viewDidLoad() 
        super.viewDidLoad()

        // Do any additional setup after loading the view.





        // Pickers

        pickerViewSignUp.delegate = self
        pickerViewSignUp.dataSource = self


        // Delegates
        genderPicker.textAlignment = .center
        genderPicker.inputView = pickerViewSignUp
        genderPicker.placeholder = "Select Gender"

        branchePicker.textAlignment = .center
        branchePicker.inputView = pickerViewSignUp
        branchePicker.placeholder = "Select Branch"

        countryPicker.textAlignment = .center
        countryPicker.inputView = pickerViewSignUp
        countryPicker.placeholder = "Select Country"



    


    // Mark: PickerViews
            // List of the SignUp used Drop Down Items

            // TextField delegate

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool 

        pickerViewSignUp.reloadAllComponents()

             return true
         


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

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

        if pickerViewSignUp == genderPicker 
            return genders.count

           else if pickerViewSignUp == branchePicker 
            return branches.count

         else return countries.count

    


    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        if pickerViewSignUp == genderPicker 
            return genders[row]
         else if  pickerViewSignUp == branchePicker 
            return branches[row]  else return countries[row]
    


    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)  

        if pickerViewSignUp == genderPicker 
            genderPicker.text = genders[row]
         else if pickerViewSignUp == branchePicker 
            branchePicker.text = branches[row]
         else countryPicker.text = countries[row]
    


【问题讨论】:

看这里的 pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int): pickerViewSignUp == genderPicker 等等...你是在比较 UITextField 和 UIPickerView...它总是错误的。 感谢您的快速答复!你能否给我一个提示如何做得更好? :) @Schaedel420 如果您点击特定按钮,是否希望显示“性别数组”?如果您点击另一个按钮,将显示另一个数组? 确切地@Putte 点击“性别”时,Pickerview 应该让用户选择性别......然后他应该选择他的分支,国家等等...... 我建议使用 3 个布尔值进行比较。 【参考方案1】:

这是我的解决方案...使用枚举来跟踪选定的状态并添加 UITextFieldDelegates:

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate 


//Mark: Properties
@IBOutlet weak var genderPicker: UITextField!
@IBOutlet weak var branchePicker: UITextField!
@IBOutlet weak var countryPicker: UITextField!

enum TextFieldType 
    case gender
    case branche
    case country
    case none


// Picker View Arrays
let genders = ["male", "female", "non-binary"]
let branches = ["Advertising", "Architecture", "Design: Product", "Design: Graphic", "Design: Fashion", "Design: Others", "Film/ Video & TV", "IT", "Museums & Galleries", "Music", "Photography", "Performing & Visual Arts", "Radio", "Others"]
let countries = ["Austria", "Australia", "USA", "Germany"]

// Picker View
var pickerViewSignUp = UIPickerView()
var selectedPikerType =  TextFieldType.none

override func viewDidLoad() 
    super.viewDidLoad()

    // Do any additional setup after loading the view.


    // Pickers

    pickerViewSignUp.delegate = self
    pickerViewSignUp.dataSource = self


    // Delegates
    genderPicker.textAlignment = .center
    genderPicker.inputView = pickerViewSignUp
    genderPicker.placeholder = "Select Gender"
    genderPicker.delegate = self

    branchePicker.textAlignment = .center
    branchePicker.inputView = pickerViewSignUp
    branchePicker.placeholder = "Select Branch"
    branchePicker.delegate = self

    countryPicker.textAlignment = .center
    countryPicker.inputView = pickerViewSignUp
    countryPicker.placeholder = "Select Country"
    countryPicker.delegate = self



// Mark: PickerViews
        // List of the SignUp used Drop Down Items

        // TextField delegate


func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool 

    switch textField 
    case genderPicker: selectedPikerType    = .gender
    case branchePicker: selectedPikerType   = .branche
    case countryPicker: selectedPikerType   = .country
    default: selectedPikerType              = .none
    


    pickerViewSignUp.reloadAllComponents()

    return true



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


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

    switch selectedPikerType 
    case .branche   : return branches.count
    case .country   : return countries.count
    case .gender    : return genders.count
    case .none      : return 0
    



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

    switch selectedPikerType 
    case .branche   : return branches[row]
    case .country   : return countries[row]
    case .gender    : return genders[row]
    case .none      : return nil
    


func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)  

    switch selectedPikerType 
    case .branche   : branchePicker.text = branches[row]
    case .country   : countryPicker.text = countries[row]
    case .gender    : genderPicker.text = genders[row]
    case .none      : break
    



我还建议您更好地命名变量...如果对象是文本字段,请使用前缀“txt”...所以 txtGender 等等。它更清晰。 还使用扩展来拆分数据源和委托,这使得它更具可读性。 :)

你可以这样写一个扩展:

extension ViewController: UITextFieldDelegate 

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool 

       switch textField 
       case genderPicker: selectedPikerType    = .gender
       case branchePicker: selectedPikerType   = .branche
       case countryPicker: selectedPikerType   = .country
       default: selectedPikerType              = .none
       


       pickerViewSignUp.reloadAllComponents()

       return true
   

【讨论】:

感谢您的快速答复!非常感谢...问题是@DungeonDev,对于性别/分支机构和国家/地区 .delegate = self 我得到:无法将“SignUpViewController”类型的值分配给“UITextFieldDelegate?” 这也是一个很好的前缀和扩展提示!谢谢:) 我已经编辑了答案,向您展示如何使用扩展。 它正在工作!非常感谢你们都是传奇!感谢大家的快速帮助! :)【参考方案2】:

在你的类中有一个全局 textField 变量来获取你正在编辑的 textField 的实例并在编辑时分配值。

在 pickerView 委托和数据源方法中,比较当前的 textField 和其余的 textField 元素。它应该可以工作。

以下是供您参考的代码:

class SignupViewController 

var currentTextfield: UITextField?

// Mark: PickerViews
// List of the SignUp used Drop Down Items

// TextField delegate

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool 
    currentTextfield = textField
    pickerViewSignUp.reloadAllComponents()
    return true



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


func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
    switch currentTextfield 
    case genderPicker:
        return genders.count
    case branchePicker:
        return branches.count
    default
        return countries.count
    

【讨论】:

以上是关于多个文本字段的 PickerView 只显示一个数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在一个视图中将一个 UIPickerView 用于多个文本字段?

具有多个文本字段输入视图的多个选取器视图 Swift

UITextField inputview 弹出 UIPickerView 在pickerview中显示问号

带有pickerview的UItextfield作为第一响应者ios

如何设置选择器视图以显示来自多个矩阵选项的数据?

如何解决uipickerview