0

I just wanna let you know that the version of Xcode that I'm working on is 7.1.1. Getting to the point, I have three Pickerviews as is shown in the image below. Main pickerview, left pickerview, and right pickerview.

The array of main pickerview has a group of names, and each name has a group of units, and the right and left pickers are supposed to have the same data. I have made a dictionary in order to sync those groups of units to where it belongs, but I could not do it.

I tagged the main Picker with 1, the left Picker with 2, and the right picker with 3. Also, all the pickers I have linked them with "dataSource" & "delegate".

http://s12.postimg.org/fj72kg29p/main_View.png


The main goal is:

I want when I pick a name i.e "Area" from the main picker its group must show or appear in the left and right pickers and so on.

I have done what I have done but I got the following error:

http://s1.postimg.org/523f3smwf/Screen_Shot_2015_11_27_at_12_39_20_AM.png

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 = []

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

    //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 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"], "Length":["Mile", "Yard", "Foot", "Inch", "Kilometer", "Meter", "Centimeter", "Millimeter"], "Power": ["Btus/Minute", "Foot-Pounds/Min", "Foot-Pounds/Sec", "Horsepower", "Kilowatts", "Watts"], "Pressure": ["Pounds/Sqr Ft", "Pounds/Sqr In", "Atmospheres", "Bars", "In of Mercury", "Cm of Mercury", "Kilograms/Sqr Meter", "Pascals"], "Speed": ["Knots", "Miles/Hr", "Miles/Min", "Feet/Min", "Feet/Sec", "Kilometers/Hr", "Kilometer/Min", "Meters/Sec"], "Temperature": ["Celsius C˚", "Fahrenheit", "Kelvin"], "Time": ["Years", "Months", "Weeks", "Days", "Hours", "Minutes", "Seconds", "Millisconds", "Microseconds", " Nanoseconds"], "Volume": ["Cupic Feet","Cubic Meter", "Gallon (Imp)", "Gallon (US)", "Quart (US)", "Pint (US)", "Fluid Oz", "Cup", "Tablespoon", "Teaspoon", "Dram (US)", "Liter"], "Weight": ["Short Ton (US)","Long Ton (UK)", "Pound (U.S)", "Ounce (US)", "Stone", "Metric Ton", "Kilogram", "Gram"]]
        mainPickerData = dataDict.allKeys;
        leftRightPickerData = dataDict.objectForKey(mainPickerData.firstObject as! String) as! NSArray

        // Linking the textFields with the pickerViews.
        textFieldLeft.inputView = leftPicker;
        textFielfRight.inputView = rightPicker;


        }

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

    // 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 leftPicker.tag == 1 {

            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.

        if(pickerView.tag == 1 ){

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

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

    }

    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
    }



}
  • I have figured it out, in your viewDidLoad why you have declared another variable let dataDict =... when you have already declare it on class level i.e. before viewDidLoad. remove the 'let' word. – Muneeba Dec 01 '15 at 06:48

1 Answers1

0

Also in your func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? properly handle attributed text for all the pickers otherswise your code will crash. You just have define attributedTitle for mainPicker. Do it for others too like the following.Make changes as per your need.

func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {

    let titleData : String?
    if(pickerView.tag == mainPicker.tag){
        titleData = mainPickerData[row] as? String;

    }
    else{

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

        titleData = leftRightPickerData[row] as? String;
    }

    let myTitle = NSAttributedString(string: titleData!, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blueColor()])
    return myTitle;

}
Muneeba
  • 1,756
  • 10
  • 11
  • THANK YOU THANK YOU THANK YOU YOU ARE THE BEST OF SWIFT ;) THANK YOU IS NOT GOOD ENOUGH FOR YOU. – Turki M. Alsayed Dec 01 '15 at 09:22
  • I just wanna ask you. Now I want to link the textfields to the left and right picker view. i.e: if a pick a meter from the left picker and foot from the right picker and I enter 1meter the foot must equal = 0.3048 WHERE CAN I DO THIS FORMULA ??? – Turki M. Alsayed Dec 01 '15 at 09:25
  • Handle the situation in the func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) , mean track the current unit selected in right and left picker and you might generate the result on some click even depending on the choice user have made on picker. Again its just an idea, make changes as per your need. – Muneeba Dec 01 '15 at 09:45
  • Can I see an example for only one of them for example : between METER vs FOOT based on my variables ( code). Then I will do the rest. – Turki M. Alsayed Dec 01 '15 at 18:29