Regarding Multiple UIPickerview

639 Views Asked by At

I have three Pickerview as it shown in the image below. I main pickerview, left pickerview, and right pickerview.

The array of main pickerview has group of names, and each name has group of units. I have made array inside array in order to show them where it belongs. But I could not do it. The array for main pivkerview apears in both thr righ and left of pickerviews.

enter image description here

here is my code :

import UIKit

class 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

There are 1 best solutions below

13
On

Instead of taking an Array, create a Dictionary for you main datasource like this and use it properly to get numberOfRowsInComponent count and 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);

if you left and right picker is supposed to contain same data, you can use one data source for that.

Also in the delegate func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?

don't check the tag on your picker instance, if you have already set tags for your pickers, then use the pickerView object in the method signature to check for tag.Do it like this

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

The reason that data is showing same in all picker is that in your func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? the condition is always true . i.e. mainPicker.tag == 1 , if you have set the tag 1 for mainPicker, hence it return same the data for all pickers.

UPDATED SOLUTION

 // 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();
    }
}

Above is the implementation for your UIPickerView delegate and datasource. Write the following code in your 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

I just have added 2 key/value pair for your code, you can add rest of the values in dataDict.

Paste the following code in your class before viewDidLoad()

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