在第三个按钮上使用 UIPickerView 进行依赖选择

Posted

技术标签:

【中文标题】在第三个按钮上使用 UIPickerView 进行依赖选择【英文标题】:Dependent Selection using UIPickerView on 3rd Button 【发布时间】:2020-06-19 22:10:50 【问题描述】:

我希望 button3 使用基于 button2 选择的 uipickerview 显示元素。 button3 将依赖于 button2。

[“圆形”:[“X”,“Y”,“Z”]]

[“正方形”:[“X”,“Y”,“Z”],“椭圆”:[“A”,“B”,“C”],“矩形”:[“1”,“ 2", "3"]]

[“三角形切割”:[“X”,“Y”,“Z”],“球体”:[“A”,“B”,“C”]]

这是当前的 xcode 脚本:

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource 


@IBOutlet weak var textField_0: UITextField!
@IBOutlet weak var textField_1: UITextField!
@IBOutlet weak var textField_2: UITextField!
@IBOutlet weak var btn1: UIButton!
@IBOutlet weak var btn2: UIButton!
@IBOutlet weak var btn3: UIButton!
@IBOutlet weak var mainPicker: UIPickerView!


private var shapeOptions = ["Option 1", "Option 2", "Option 3"]

private var shape1 = [["Round"],
    ["Square", "Oval", "Rectangle"],
    ["Triangle", "Sphere"]]

private var shape2 = [["X", "Y", "Z"],
    ["A", "B", "C"],
    ["1", "2", "3"]]

private var _currentSelection: Int = 0

var currentSelection: Int 
    get 
        return _currentSelection
    
    set 
        _currentSelection = newValue
        mainPicker.reloadAllComponents()

        textField_0.text = shapeOptions[_currentSelection]
        textField_1.text = shape1[_currentSelection][0]
        textField_2.text = shape2[_currentSelection][0]
        
    

    override func viewDidLoad() 
        super.viewDidLoad()
        currentSelection = 0;
    

    @IBAction func btn1Clicked(_ sender: Any) 
        mainPicker.delegate = self
        mainPicker.dataSource = self
        mainPicker.tag = 0
        mainPicker.isHidden = false
    

    @IBAction func btn2Clicked(_ sender: Any) 
        mainPicker.delegate = self
        mainPicker.dataSource = self
        mainPicker.tag = 1
        mainPicker.isHidden = false
    

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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        if pickerView.tag == 0 
            return shapeOptions.count
         else if pickerView.tag == 1 
            return shape1[currentSelection].count
         else 
            return shape2[currentSelection].count
        
    

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        if pickerView.tag == 0 
            return shapeOptions[row]
         else if pickerView.tag == 1 
            return shape1[currentSelection][row]
         else 
            return shape2[currentSelection][row]
        
    

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        if pickerView.tag == 0 
            currentSelection = row
            textField_0.text = shapeOptions[row]
            textField_0.resignFirstResponder()
         else if pickerView.tag == 1 
            textField_1.text = shape1[currentSelection][row]
            textField_1.resignFirstResponder()
         else 
            textField_2.text = shape2[currentSelection][row]
            textField_2.resignFirstResponder()
        
    

【问题讨论】:

你能详细解释一下吗?您有三个按钮可以更改pickerView 的选择吗?当我点击 button3 时会发生什么? @rs7 例如:BUTTON1(人类、动物、植物); BUTTON2(人类:美国、欧洲、亚洲);动物:(狗、猫、爬行动物);植物:(水果、蔬菜、肉类); BUTTON3(美式:男、女);欧洲的...;亚洲...;狗(狼、鬣狗、狐狸);猫(老虎、狮子、猎豹);爬行动物...我希望我的解释很清楚:-D 或者这可能会帮助link 所以首先假设您在pickerView 中看到了一个由[人类、动物、植物] 组成的选择。您选择人类并点击 button1,然后 pickerView 选择更改为 [American, European, Asian]。您选择欧洲并点击按钮 2,现在选择变为 [男性,女性]。最后,您使用按钮 3 进行最后选择。我理解对了吗?如果是,为什么需要 3 个不同的按钮?它们会一个接一个地出现吗? @rs7 点击Button1时pickerview会显示[human, animals, 植物],然后点击Button2pickerview会显示[American, European, Asian],然后点击Button3pickerview会显示[男,女]...每个按钮都有自己的标签,这就是需要它的原因。在我的脚本中,Button1 和 Button2 运行良好,但在 Button3 上却不行。 【参考方案1】:

几件事:

您的代码中缺少Button3 函数。 您无需在每次单击按钮时设置pickerview 委托/数据源。 如果我正确理解您想要的内容,您无需在每次按下按钮时都取消隐藏 pickerView。只需在按下第一个按钮时取消隐藏即可。 我不确定 textField 的作用,但请考虑将 textField 代码移动到按钮函数中。 我在下面修改了您的代码。您只想在点击按钮以确认选择时重新加载 pickerView。您在代码中所做的是每次用户更改选择器选择时重新加载 pickerView。 (可选)您可以使用带有 didSet 块的 pickerViewIndex 变量来重新加载pickerView,而不是使用标签。在函数内部,您无需为 pickerView.tag 赋值,而是为 pickerViewIndex 赋值。

    var currentSelection: Int 
    get 
        return _currentSelection
    
    set 
        _currentSelection = newValue
        // Consider moving the code below to the buttons functions
        textField_0.text = shapeOptions[_currentSelection]
        textField_1.text = shape1[_currentSelection][0]
        textField_2.text = shape2[_currentSelection][0]
        
    
    override func viewDidLoad() 
        super.viewDidLoad()
        currentSelection = 0;

        mainPicker.delegate = self
        mainPicker.dataSource = self

    

    @IBAction func btn1Clicked(_ sender: Any) 
        mainPicker.tag = 0
        mainPicker.isHidden = false
        mainPicker.reloadAllComponents()
    

    @IBAction func btn2Clicked(_ sender: Any) 
        mainPicker.tag = 1
        mainPicker.reloadAllComponents()
    

    @IBAction func btn3Clicked(_ sender: Any) 
        mainPicker.tag = 2
        mainPicker.reloadAllComponents()
    

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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        if pickerView.tag == 0 
            return shapeOptions.count
         else if pickerView.tag == 1 
            return shape1[currentSelection].count
         else 
            return shape2[currentSelection].count
        
    

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        if pickerView.tag == 0 
            return shapeOptions[row]
         else if pickerView.tag == 1 
            return shape1[currentSelection][row]
         else 
            return shape2[currentSelection][row]
        
    

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        if pickerView.tag == 0 
            currentSelection = row
            textField_0.text = shapeOptions[row]
            textField_0.resignFirstResponder()
         else if pickerView.tag == 1 
            currentSelection = row
            textField_1.text = shape1[currentSelection][row]
            textField_1.resignFirstResponder()
         else 
            currentSelection = row
            textField_2.text = shape2[currentSelection][row]
            textField_2.resignFirstResponder()
        
    

【讨论】:

首先,我要感谢您花时间编写代码。我很感激。但是还没有满足button3部分。 [选项1:“圆形”:[“X”,“Y”,“Z”]] [选项2:“方形”:[“X”,“Y”,“Z”],“椭圆”:[“A ", "B", "C"], "矩形": ["1", "2", "3"]] [选项 3: "三角形切割": ["X", "Y", "Z" ], "球体": ["A", "B", "C"]] 我没有设置合适的标签。我更新了我的答案。您需要将按钮 3 函数的第一行从 mainPicker.tag = 1 更改为 mainPicker.tag = 2,这样就可以了。 我发布了答案。感谢您的所有回复。我很感激。现在,我需要的下一个帮助是根据选择从列中的 CSV 文件中获取值。【参考方案2】:

@rs7 我能从某人那里得到答案,这就是我正在寻找的答案:

private var shapeOptions = ["Option 1", "Option 2", "Option 3"]

private var shape = [["Round"],
    ["Square", "Oval", "Rectangle"],
    ["Triangle", "Sphere"]]

private var sizeA:[[String]] = [["X", "Y", "Z"]]
private var sizeB:[[String]] = [["A", "B", "C"]]
private var sizeC:[[String]] = [["1", "2", "3"]]

    private var sizes:[[[String]]]?
 

    var currentTypeSelection: Int? 
        didSet
            mainPicker.reloadAllComponents()
        
    

    var currentSizeSelection: Int? 
        didSet
            mainPicker.reloadAllComponents()
        
    

    override func viewDidLoad() 
        super.viewDidLoad()
        self.sizes = [sizeA, sizeB, sizeC]

        currentTypeSelection = 0;
        currentSizeSelection = 0;
    
    
    @IBAction func btn1Clicked(_ sender: Any) 
        mainPicker.delegate = self
        mainPicker.dataSource = self
        mainPicker.tag = 0
        mainPicker.isHidden = false
    
    
    @IBAction func btn2Clicked(_ sender: Any) 
        mainPicker.delegate = self
        mainPicker.dataSource = self
        mainPicker.tag = 1
        mainPicker.isHidden = false
    
    
    @IBAction func btn3Clicked(_ sender: Any) 
        mainPicker.delegate = self
        mainPicker.dataSource = self
        mainPicker.tag = 2
        mainPicker.isHidden = false
    
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int 
        return 1
    

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        if pickerView.tag == 0 
            return shapeOptions.count
         else if pickerView.tag == 1 
            return shape[currentTypeSelection!].count
         else 
            return sizes![currentTypeSelection!][currentSizeSelection!].count
         
    

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        if pickerView.tag == 0 
            return shapeOptions[row]
         else if pickerView.tag == 1 
            return shape[currentTypeSelection!][row]
         else 
            return sizes![currentTypeSelection!][currentSizeSelection!][row]
        
    

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        if pickerView.tag == 0 
            currentTypeSelection = row
            textField_0.text = shapeOptions[row]
            textField_0.resignFirstResponder()
            currentSizeSelection = 0
         else if pickerView.tag == 1 
            currentSizeSelection = row
            textField_1.text = shape[currentTypeSelection!][row]
            textField_1.resignFirstResponder()
         else 
            textField_2.text = sizes![currentTypeSelection!][currentSizeSelection!][row]
            textField_2.resignFirstResponder()
        
    

【讨论】:

以上是关于在第三个按钮上使用 UIPickerView 进行依赖选择的主要内容,如果未能解决你的问题,请参考以下文章

使用 UIToolBar 上的完成按钮关闭 UIPickerView

Swift - UIPickerView 的带有完成按钮的 UIToolbar 在横向上消失

Objective C 使用“完成”按钮实现 UIPickerView

使用工具栏按钮更改 UIPickerView 值

如何在同一个 Viewcontroller 上使用 UIPickerview 和 UIDatePicker?

如何在uipickerview上添加完成按钮