0

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 Answers1

0

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!
Muneeba
  • 1,756
  • 10
  • 11
  • Yes you alright regarding the left and right pickerview, they suppose have the same data. I'm sorry I have some questions for you... 1- How can I share the datasourse and delegate between the left and right pickerview. Should I remove the delegate and sourse from the mainpickerview. 2- let leftPickerData = dataDict.objectForKey("Energy"); What about the other groups, How can I add them in same variable. and shall I do the same for the right ?? 3- – Turki M. Alsayed Nov 26 '15 at 08:33
  • for your last comment regarding the tag, what should I do. Currently, nothing shows up in any of them. – Turki M. Alsayed Nov 26 '15 at 08:40
  • Check my updated answer, hope it will solve your problem and on change row in your main picker view the left and right view will update accordingly – Muneeba Nov 26 '15 at 09:30
  • For adding other groups in dataDict follow the same format i.e. "your key" : [ array for that key] , "yournextKey" : [ array for that key] – Muneeba Nov 26 '15 at 09:33
  • I just wanna let you know that I linked the mainPicker, left, and right with datasourse and delegate. Also, I have given the mainPicker 0 tag, the left 1 tag, and the right 2 tag. Regarding you updated solution, I have got unresolved error for the line : leftRightPickerData = dataDict.objectForKey(mainPickerData.firstObject as! String) as! NSArray when I add "let" before it, I got another error for "dataDict" that says unresolved identifier. – Turki M. Alsayed Nov 26 '15 at 20:48
  • I have updated my answer. Please check it and remove the changes you have you have mentioned in your above comment. – Muneeba Nov 27 '15 at 04:19
  • Thank you Sir for your concern, I highly appreciate your time. Would you please check these two links that I got after I made the recommended changes. http://s1.postimg.org/523f3smwf/Screen_Shot_2015_11_27_at_12_39_20_AM.png http://s11.postimg.org/f5mf2tob7/111.png Thank you in advance – Turki M. Alsayed Nov 27 '15 at 06:50
  • Set the datasource and delegate for all the pickers – Muneeba Nov 27 '15 at 07:30
  • Done >>>> datasourse & delegate for all pickers. Did you see the second image that shows the error ???? I posted two links .. ;) – Turki M. Alsayed Nov 27 '15 at 08:49
  • yes i saw that, you still getting that error? Whats your Xcode version? – Muneeba Nov 27 '15 at 09:46
  • you still having that issue? – Muneeba Nov 30 '15 at 04:19
  • Yes I still have the issue ... check out the last update code : http://stackoverflow.com/questions/33966224/multiple-uipickerview-errors – Turki M. Alsayed Dec 01 '15 at 04:49
  • Check the comment on this link. http://stackoverflow.com/questions/33966224/multiple-uipickerview-errors – Muneeba Dec 01 '15 at 06:48