关于多个 UIPickerview

Posted

技术标签:

【中文标题】关于多个 UIPickerview【英文标题】:Regarding Multiple UIPickerview 【发布时间】:2015-11-26 06:09:54 【问题描述】:

我有三个 Pickerview,如下图所示。我主要有pickerview、left pickerview和right pickerview。

主pickerview的数组有一组名字,每个名字都有一组单元。我在数组中创建了数组,以便向他们展示它所属的位置。但我做不到。主 pivkerview 的数组出现在 pickerviews 的右侧和左侧。

enter image description here

这是我的代码:

import UIKit

类 ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate

@IBOutlet weak var mainPicker: UIPickerView!
@IBOutlet weak var leftPicker: UIPickerView!
@IBOutlet weak var rightPicker: UIPickerView!
@IBOutlet weak var textFieldLeft: UITextField!
@IBOutlet weak var textFielfRight: UITextField!
@IBOutlet weak var equal: UILabel!

var mainPickerData = []
var leftPickerData = []
var rightPickerData = []

//yourPicker.backgroundColor = UIColor(patternImage: UIImage(named: "back.jpg")!)


override func viewDidLoad() 
    super.viewDidLoad()

    // Connect data:
    self.mainPicker.delegate = self
    self.mainPicker.dataSource = self

    self.leftPicker.delegate = self
    self.leftPicker.dataSource = self

    self.rightPicker.delegate = self
    self.rightPicker.dataSource = self

    let theWidth = view.frame.size.width
    let theHeight = view.frame.size.height

    mainPicker.center = CGPointMake(theWidth/2, theHeight/2 - 182.5)
    leftPicker.center = CGPointMake(theWidth/2 - 100, theHeight/2)
    rightPicker.center = CGPointMake(theWidth/2 + 100, theHeight/2)
    textFieldLeft.center = CGPointMake(theWidth/2 - 90, theHeight/2 + 110)
    textFielfRight.center = CGPointMake(theWidth/2 + 90, theHeight/2 + 110)
    equal.center = CGPointMake(theWidth/2, theHeight/2 + 110)



    let Area = ["Square Mile", "Square Yard", "Square Foot", "Square Inch", "Hectare", "Acre", "Square Kilometer", "Square Meter", "Square Centimeter", " Square Millimeter"]

    let Energy = ["Btus", "Calories", "Ergs", "Foot-Pounds", "Joules", "Kilogram-Calories", "Kilogram-Meters", "Kilowatt-Hours", "Newton-Meters", "Watt-Hours"]

    let Length = ["Mile", "Yard", "Foot", "Inch", "Kilometer", "Meter", "Centimeter", "Millimeter"]

    let Power = ["Btus/Minute", "Foot-Pounds/Min", "Foot-Pounds/Sec", "Horsepower", "Kilowatts", "Watts"]

    let Pressure = ["Pounds/Sqr Ft", "Pounds/Sqr In", "Atmospheres", "Bars", "In of Mercury", "Cm of Mercury", "Kilograms/Sqr Meter", "Pascals"]

    let Speed = ["Knots", "Miles/Hr", "Miles/Min", "Feet/Min", "Feet/Sec", "Kilometers/Hr", "Kilometer/Min", "Meters/Sec"]

    let Temperature = ["Celsius C˚", "Fahrenheit", "Kelvin"]

    let Time = ["Years", "Months", "Weeks", "Days", "Hours", "Minutes", "Seconds", "Millisconds", "Microseconds", " Nanoseconds"]

    let Volume = ["Cupic Feet","Cubic Meter", "Gallon (Imp)", "Gallon (US)", "Quart (US)", "Pint (US)", "Fluid Oz", "Cup", "Tablespoon", "Teaspoon", "Dram (US)", "Liter"]

    let Weight = ["Short Ton (US)","Long Ton (UK)", "Pound (U.S)", "Ounce (US)", "Stone", "Metric Ton", "Kilogram", "Gram"]

    // Pickerview at the center top side of Screen.
    mainPickerData = ["Area", "Energy", "Length", "Power", "Pressure", "Speed", "Temperature", "Time", "Volume", "Weight"]

    // Pickerview at the lower left side of Screen.
    leftPickerData = [["Square Mile", "Square Yard", "Square Foot", "Square Inch", "Hectare", "Acre", "Square Kilometer", "Square Meter", "Square Centimeter", " Square Millimeter"], ["Square Mile", "Square Yard", "Square Foot", "Square Inch", "Hectare", "Acre", "Square Kilometer", "Square Meter", "Square Centimeter", " Square Millimeter"], ["Mile", "Yard", "Foot", "Inch", "Kilometer", "Meter", "Centimeter", "Millimeter"], ["Btus/Minute", "Foot-Pounds/Min", "Foot-Pounds/Sec", "Horsepower", "Kilowatts", "Watts"], ["Pounds/Sqr Ft", "Pounds/Sqr In", "Atmospheres", "Bars", "In of Mercury", "Cm of Mercury", "Kilograms/Sqr Meter", "Pascals"], ["Knots", "Miles/Hr", "Miles/Min", "Feet/Min", "Feet/Sec", "Kilometers/Hr", "Kilometer/Min", "Meters/Sec"],["Celsius C˚", "Fahrenheit", "Kelvin"], ["Years", "Months", "Weeks", "Days", "Hours", "Minutes", "Seconds", "Millisconds", "Microseconds", " Nanoseconds"], ["Cupic Feet","Cubic Meter", "Gallon (Imp)", "Gallon (US)", "Quart (US)", "Pint (US)", "Fluid Oz", "Cup", "Tablespoon", "Teaspoon", "Dram (US)", "Liter"], ["Short Ton (US)","Long Ton (UK)", "Pound (U.S)", "Ounce (US)", "Stone", "Metric Ton", "Kilogram", "Gram"]]

    // Pickerview at the lower Right side of Screen.
    rightPickerData = [["Square Mile", "Square Yard", "Square Foot", "Square Inch", "Hectare", "Acre", "Square Kilometer", "Square Meter", "Square Centimeter", " Square Millimeter"], ["Square Mile", "Square Yard", "Square Foot", "Square Inch", "Hectare", "Acre", "Square Kilometer", "Square Meter", "Square Centimeter", " Square Millimeter"], ["Mile", "Yard", "Foot", "Inch", "Kilometer", "Meter", "Centimeter", "Millimeter"], ["Btus/Minute", "Foot-Pounds/Min", "Foot-Pounds/Sec", "Horsepower", "Kilowatts", "Watts"], ["Pounds/Sqr Ft", "Pounds/Sqr In", "Atmospheres", "Bars", "In of Mercury", "Cm of Mercury", "Kilograms/Sqr Meter", "Pascals"], ["Knots", "Miles/Hr", "Miles/Min", "Feet/Min", "Feet/Sec", "Kilometers/Hr", "Kilometer/Min", "Meters/Sec"],["Celsius C˚", "Fahrenheit", "Kelvin"], ["Years", "Months", "Weeks", "Days", "Hours", "Minutes", "Seconds", "Millisconds", "Microseconds", " Nanoseconds"], ["Cupic Feet","Cubic Meter", "Gallon (Imp)", "Gallon (US)", "Quart (US)", "Pint (US)", "Fluid Oz", "Cup", "Tablespoon", "Teaspoon", "Dram (US)", "Liter"], ["Short Ton (US)","Long Ton (UK)", "Pound (U.S)", "Ounce (US)", "Stone", "Metric Ton", "Kilogram", "Gram"]]


// The number of columns of data
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int 
    return 1


// The number of rows of data
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 

    if mainPicker.tag == 1 

        return mainPickerData.count

    else if leftPicker.tag == 2 

        return leftPickerData.count

    else

        return rightPickerData.count
    


// The data to return for the row and component (column) that's being passed in
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 

    if mainPicker.tag == 1 

        return mainPickerData[row] as? String
    else if leftPicker.tag == 2 

        return leftPickerData[row] as? String

    else

        return rightPickerData[row] as? String
    




// Catpure the picker view selection
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    // This method is triggered whenever the user makes a change to the picker selection.
    // The parameter named row and component represents what was selected.


override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) 

    self.view.endEditing(true)



func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? 
    let titleData = mainPickerData[row]
    let myTitle = NSAttributedString(string: titleData as! String, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blueColor()])
    return myTitle

【问题讨论】:

【参考方案1】:

不要使用Array,而是像这样为您的主数据源创建一个Dictionary,并正确使用它来获取numberOfRowsInComponent 计数和titleForRow

let dataDict:NSMutableDictionary = ["Area":["Square Mile", "Square Yard", "Square Foot", "Square Inch", "Hectare", "Acre", "Square Kilometer", "Square Meter", "Square Centimeter", " Square Millimeter"]
        ,"Energy":["Btus", "Calories", "Ergs", "Foot-Pounds", "Joules", "Kilogram-Calories", "Kilogram-Meters", "Kilowatt-Hours", "Newton-Meters", "Watt-Hours"]]
let mainPickerData = dataDict.allKeys;
let leftPickerData = dataDict.objectForKey("Energy"); //here you can pas the string return from pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) delegate for main picker

print(mainPickerData);
print(leftPickerData);

如果您的左右选择器应该包含相同的数据,您可以为此使用一个数据源。

也在委托func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -&gt; String?

不要检查你的选择器实例上的标签,如果你已经为你的选择器设置了标签,那么使用方法签名中的pickerView对象来检查标签。这样做

if pickerView.tag == 1 ... 
else if (pickerView.tag == 2) ...

数据在所有选择器中显示相同的原因是您的func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -&gt; String? 条件始终为真。即 mainPicker.tag == 1 ,如果您为 mainPicker 设置了标签 1,因此它为所有选择器返回相同的数据。

更新的解决方案

 // The number of columns of data
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int 
    return 1


// The number of rows of data
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 

    switch (pickerView.tag) 

    case mainPicker.tag:

        return mainPickerData.count

    case leftPicker.tag,rightPicker.tag:

        let currentSelectedIndex = mainPicker.selectedRowInComponent(0)
        leftRightPickerData = (dataDict.objectForKey(mainPickerData[currentSelectedIndex] as! String) as! NSArray)

        return leftRightPickerData.count;

    default:
        break;
    
    return 0;
//F.E

// The data to return for the row and component (column) that's being passed in
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 

    switch (pickerView.tag) 

    case mainPicker.tag:

        return mainPickerData[row] as? String;

    case leftPicker.tag,rightPicker.tag:

        let currentSelectedIndex = mainPicker.selectedRowInComponent(0)
        leftRightPickerData = (dataDict.objectForKey(mainPickerData[currentSelectedIndex] as! String) as! NSArray)

        return leftRightPickerData[row] as? String;

    default:
        break;
    

    return "";



// Catpure the picker view selection
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    // This method is triggered whenever the user makes a change to the picker selection.
    // The parameter named row and component represents what was selected.
    if(pickerView.tag == 1 )

        let currentSelectedIndex = mainPicker.selectedRowInComponent(0)
        leftRightPickerData = (dataDict.objectForKey(mainPickerData[currentSelectedIndex] as! String) as! NSArray)

        leftPicker.reloadAllComponents();
        rightPicker.reloadAllComponents();
    

以上是您的UIPickerView delegatedatasource 的实现。 在您的viewDidLoad()中写入以下代码

    dataDict = ["Area":["Square Mile", "Square Yard", "Square Foot", "Square Inch", "Hectare", "Acre", "Square Kilometer", "Square Meter", "Square Centimeter", " Square Millimeter"]
        ,"Energy":["Btus", "Calories", "Ergs", "Foot-Pounds", "Joules", "Kilogram-Calories", "Kilogram-Meters", "Kilowatt-Hours", "Newton-Meters", "Watt-Hours"]]
    mainPickerData = dataDict.allKeys;
    leftRightPickerData = dataDict.objectForKey(mainPickerData.firstObject as! String) as! NSArray

我刚刚为您的代码添加了 2 个键/值对,您可以在 dataDict 中添加其余的值。

viewDidLoad()之前的类中粘贴以下代码

var dataDict:NSMutableDictionary!
var mainPickerData:NSArray!
var leftRightPickerData:NSArray!

【讨论】:

是的,关于左右选择器视图,你没问题,他们假设有相同的数据。很抱歉,我有一些问题要问您... 1- 我如何在左右选择器视图之间共享数据源和委托。我应该从 mainpickerview 中删除代表和源吗? 2- 让 leftPickerData = dataDict.objectForKey("Energy");其他组呢,我如何将它们添加到同一个变量中。我应该为权利做同样的事情吗? 3- 对于您对标签的最后评论,我该怎么办。目前,其中任何一个都没有显示任何内容。 检查我更新的答案,希望它能解决您的问题,并且在您的主选择器视图中更改行时,左右视图将相应更新 要在 dataDict 中添加其他组,请遵循相同的格式,即 "your key" : [array for that key] , "yournextKey" : [array for that key] 我只是想让您知道,我将 mainPicker、left 和 right 与 datasource 和 delegate 关联起来。另外,我给出了 mainPicker 0 标签、左标签 1 和右标签 2。关于您更新的解决方案,我有未解决的错误:leftRightPickerData = dataDict.objectForKey(mainPickerData.firstObject as!String) as! NSArray 当我在它之前添加“let”时,“dataDict”出现另一个错误,显示未解析的标识符。

以上是关于关于多个 UIPickerview的主要内容,如果未能解决你的问题,请参考以下文章

关于 MapStruct 映射的多个问题

关于联合和多个整数值

40多个关于人脸检测/识别的API库和软件

关于 Scala 隐含多个类型参数的问题

关于合并多个 svn repos 的说明

关于tomcat 多个配置多个host加载多次,导致initSerlet加载多次