UIPickerView - 条件显示

Posted

技术标签:

【中文标题】UIPickerView - 条件显示【英文标题】:UIPickerView - conditional display 【发布时间】:2016-09-01 03:18:14 【问题描述】:

我是 swift 新手,对 UIPickerView 有疑问。

我已经创建了两个pickerview

一个值 - A、B、C、F

两个值 - B、C、D、E

我现在想在这两个选择器视图中实现一个逻辑。

逻辑是,如果在第一个pickerview 中选择了B 和C,那么第二个pickerview 将没有B 和C 供用户选择。我怎样才能做到这一点?

我是 swift 的初学者,所以任何提示都将不胜感激。

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource 

    @IBOutlet weak var Picker1: UIPickerView!

    @IBOutlet weak var Picker2: UIPickerView!
    @IBOutlet weak var label: UILabel!

    var savedVal1 = "" as String
    var savedVal2 = "" as String

    var Array = ["A", "B", "C", "F"]
    var Array2 = ["B", "C", "D", "E"]

    var PlacementAnswer = 0

    override func viewDidLoad() 
        super.viewDidLoad()

        Picker1.delegate = self
        Picker1.dataSource = self
        Picker1.tag = 1

        Picker2.delegate = self
        Picker2.dataSource = self
        Picker2.tag = 2
    

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        if pickerView == Picker1
         return Array[row] 
        else if pickerView == Picker2
         return Array2[row] 
        return ""
    

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        if pickerView == Picker1
         return Array.count 
        else if pickerView == Picker2
         return Array2.count 
        return 1
    

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int 

        return 1
    

【问题讨论】:

【参考方案1】:

为您的pickerView 实现选择委托功能:

var array3 = Array2 //Create a copy of Array 2

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    //Check if picker is picker1 and the chosen value is "B" or "C"
    if pickerView == Picker1 
        if Array[row] == "B" || Array[row] == "C" 
            //Check if "B" and "C" is available
            if let index = Array2.indexOf(Array[row]) 
                //Remove it from Picker2 datasource array and reload it
                Array2.removeAtIndex(index)
                Picker2.reloadAllComponents()
            
        
        else 
            //If choose another option other than "B" and "C", revert back to the first array
            Array2 = array3
            Picker2.reloadAllComponents()
        
    

老实说,你应该阅读 Swift 代码发明,变量应该是小写,而不是大写

【讨论】:

感谢您的帮助。只是一个问题-在此命令上“Array2.removeAtIndex(Array2.indexOf(Array[row]))”我有一条错误消息-“可选类型'index'的值?没有打开,你的意思是用'!'或者 '?' " 对不起,我只是在没有编译器的情况下编写它,所以您可以按照系统的修复并添加! 非常感谢。另一个问题出现了 - 在我在第一个 pickerView 中选择一个值后,第二个 pickerView 中的相应值被删除。当我在第一个 pickerView 中重新选择相同的值时,出现错误。【参考方案2】:

其中一种方法是,当用户不会感到困惑时,真正发生的事情是不要从选择器中删除项目。而是向他展示您的真正意思,他会更好地理解这些选项在某些组合中不可用。解决方案可以更简单。

说明:用户从第一个选择器中选择 B 或 C。然后,如果选择了第二个选择器中的 B 或 C,它跳转到下一个可用选项。 此外,我们可以更改不可用的行的颜色。

//REMOVED METHOD - not able to change title color
/*func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
    if pickerView == Picker1
     return Array[row] 
    else if pickerView == Picker2
     return Array2[row] 
    return ""
*/

//ADDED METHOD - for styling of your UIPickerView title
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? 

    let string = pickerView == Picker1 ? Array[row] : Array2[row]

    if (pickerView == Picker2 && (row == 1 || row == 2)) 
        return NSAttributedString( // gray row, when B or C in Picker2
            string: string,
            attributes: [NSForegroundColorAttributeName: UIColor.gray]
        )
    

    return NSAttributedString( // common row
        string: string,
        attributes: nil)


//UPDATED METHOD - to reset second picker if user selects B or C from the second picker
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 

    if (pickerView == Picker1 && (row == 1 || row == 2)) 
        print("You selected B or C in first PickerView")
     else if (pickerView == Picker2 && (row == 0 || row == 1)) 
        // if already set B or C in first Picker, and user has selected B or C in second picker,
        // jump to the next available option
        Picker2.selectRow(3, inComponent: 0, animated: true)
    

【讨论】:

我在 Swift 3.0 中编写了代码,所以如果你复制粘贴,你应该将代码更新到以前的 Swift 版本。

以上是关于UIPickerView - 条件显示的主要内容,如果未能解决你的问题,请参考以下文章

使用 UIPickerView 从 json 加载数据

UIPickerView - 条件显示

如何与 Xamarin UITest 中的自定义键盘进行交互?

动态 UIPickerView 竞争条件?

UIPickerView 显示问题

根据数据显示数据 UIPickerView