Unable to use two UIPickerViews on one viewcontroller

巧了我就是萌 提交于 2019-12-11 18:32:37

问题


I currently have a view controller with 3 text fields:

customerTextField

manufacturerTextField

modelTextField

When selecting manufacturerTextField I need the UIPicker associated with https://www.example.com/example/Manufacturer.php to appear.

This UIPicker by design has two columns that are populated using JSON data. When making the selection the UIPicker populates both manufacturerTextField and modelTextField

When the user selects customerTextField I would like the UIPickerView to show the data from https://www.example.com/example/customer.php

This should only be a single column selection.

UPDATED ISSUE:

The following is what I currently have, for some reason when selecting customerTextField the UIPicker with two columns comes up with manufacturerTextField data.

    import UIKit

class CreateRMA_ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate {



        @IBOutlet weak var customerTextField: UITextField!
        @IBOutlet weak var manufacturerTextField: UITextField!
        @IBOutlet weak var modelTextField: UITextField!

        var selectedTextField = UITextField()

    struct Category {
        var name: String
        var items: [String]
    }
    var allCategories = [Category]()
    var selectedCategory:Category?
    var selectedItem: String?

    var pickerView: UIPickerView!
    var values: [AnyObject] = []

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    selectedTextField = textField
    pickerView.isHidden = false
    return true
}

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        if selectedTextField == customerTextField {
            return 1
        } else if selectedTextField == manufacturerTextField {
            return selectedCategory == nil ? 1 : 2
        } else {//modelTextField
            return 2
        }
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if selectedTextField == customerTextField {
            return values.count
        } else if selectedTextField == manufacturerTextField {
            return component == 0 ? allCategories.count : selectedCategory?.items.count ?? 0
        } else {//modelTextField
            return selectedCategory?.items.count ?? 0
        }
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if selectedTextField == customerTextField {
            return values[row] as? String
        } else if selectedTextField == manufacturerTextField {
            if component == 0 {
                return allCategories[row].name
            } else {
                return selectedCategory?.items[row]
            }
        } else {//modelTextField
            return selectedCategory?.items[row]
        }
    }


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

        if component == 0 {
            selectedCategory = allCategories[row]
            manufacturerTextField.text = allCategories[row].name
            pickerView.reloadAllComponents()
        } else {
            selectedItem = selectedCategory?.items[row]
            modelTextField.text = selectedCategory?.items[row]
        }
    }







    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }


        override func viewDidLoad() {
            super.viewDidLoad()

            pickerView = UIPickerView()
            pickerView.dataSource = self
            pickerView.delegate = self
            manufacturerTextField.inputView = pickerView






            //get the values from sql/Json
            let url = NSURL(string: "https://www.example.com/test/service.php")

            let data = NSData(contentsOf: url! as URL)
            var tmpValues = try! JSONSerialization.jsonObject(with: data! as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSArray
            tmpValues = tmpValues.reversed() as NSArray
            reloadInputViews()


            for candidate in tmpValues {
                if let cdict = candidate as? NSDictionary {

                    //fullName is the column name in sql/json
                    let names = cdict["customer"]
                    self.values.append(names! as AnyObject)


                }
            }

            if let url = URL(string: "https://www.example.com/test/Make_Model.php"),
                let data = try? Data(contentsOf: url),
                let tmpValues = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [[String:String]] {
                let tempCategories = tmpValues?.reduce(into: [String:[String]](), { (dict, value) in
                    if let manufacturer = value["manufacturer"], let model = value["model"] {
                        dict[manufacturer, default:[]].append(model)
                    }
                })
                for category in (tempCategories ?? [:]) {
                    allCategories.append(Category(name: category.key, items: category.value))
                }
                pickerView.reloadAllComponents()
            }
    }



}

回答1:


When you have multiple text fields having the same picker view as input view you need to keep a reference to the currently selected text field

@IBOutlet weak var customerTextField: UITextField!
@IBOutlet weak var manufacturerTextField: UITextField!
@IBOutlet weak var modelTextField: UITextField!
var selectedTextField = UITextField()

Assign selected textfield to this temp textfield in textFieldShouldBeginEditing

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    selectedTextField = textField
    pickerView.reloadAllComponents()
    pickerView.isHidden = false
    return true
}

And check which textfield is selected in picker view datasource and delegate methods and use appropriate data source.

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    if selectedTextField == customerTextField {
        return 1
    } else if selectedTextField == manufacturerTextField {
        return selectedCategory == nil ? 1 : 2
    } else {//modelTextField
        return 2
    }
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if selectedTextField == customerTextField {
        return values.count
    } else if selectedTextField == manufacturerTextField {
        return component == 0 ? allCategories.count : selectedCategory?.items.count ?? 0
    } else {//modelTextField
        return selectedCategory?.items.count ?? 0
    }
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if selectedTextField == customerTextField {
        return values[row] as? String
    } else if selectedTextField == manufacturerTextField {
        if component == 0 {
            return allCategories[row].name
        } else {
            return selectedCategory?.items[row]
        }
    } else {//modelTextField
        return selectedCategory?.items[row]
    }
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if selectedTextField == customerTextField {
        customerTextField.text = values[row] as? String
    } else if selectedTextField == manufacturerTextField {
        if component == 0 {
            selectedCategory = allCategories[row]
            manufacturerTextField.text = allCategories[row].name
            pickerView.reloadAllComponents()
        } else {
            selectedItem = selectedCategory?.items[row]
            modelTextField.text = selectedCategory?.items[row]
        }
    } else {//modelTextField
        modelTextField.text = selectedCategory?.items[row]
    }
}


来源:https://stackoverflow.com/questions/55860092/unable-to-use-two-uipickerviews-on-one-viewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!