2

I'm making a GPA calculator using swift and I've run into some problems. I created a picker view with all the letter grades (A to F). I've put 7 text fields (one for each course). I want the user to tap on a textfield and the pickerview should appear, and the grade selected would appear in the textfield. I've managed to do that for the first textfield but I dont know how to write the code that allows me to pick the grade for each textfield. I've tried different methods but I always end up changing the first textfield only.

Any help is appreciated :-)

Here is my code (gradeOne is a textfield for course 1, gradeTwo for course 2, etc.):

import UIKit

class GPA: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

@IBOutlet var gradeOne: UITextField!

@IBOutlet var gradeTwo: UITextField!





//Grades array

var grades = ["A+/A (85-100)", "A- (80-84)", "B+ (77-79)", "B (73-76)", "B- (70-72)", "C+ (67-69)", "C (63-66)", "C- (60-62)", "D+ (57-59)", "D (53-56)", "D- (50-52)", "F (0-49)"]


//Grade 1 Picker
func numberOfComponentsInPickerView(gradePickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(gradePickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return grades.count
}

func pickerView(gradePickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return grades[row]
}

func pickerView(gradePickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    gradeOne.text = grades[row]

}



//Make keyboard disappear


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let gradePickerView = UIPickerView()
    gradePickerView.delegate = self
    gradeOne.inputView = gradePickerView


    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
    view.addGestureRecognizer(tap)

}

func dismissKeyboard() {
    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)
}

}

3 Answers3

4

You should set gradePickerView as the inputView for all your textfields

gradeTwo.inputView = gradePickerView
gradeThree.inputView = gradePickerView
// set for rest of textfields

and then in your pickerView:didSelectRow: method you need to set the text to the active text field at the time. I suggest setting the active textfield using UITextFieldDelegate

var activeField: UITextField?

override func viewDidLoad() {
    // Set VC as textfield's delegate
    gradeTwo.delegate = self
    gradeThree.delegate = self
    // Set for rest of textfields
}

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    activeField = textField
}

func pickerView(gradePickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    activeField.text = grades[row]
}
Dickson Leonard
  • 518
  • 5
  • 14
  • Perfect!! it worked. Just one tiny detail you left out: textFieldShouldBeginEditing should return true :-) –  Jul 12 '16 at 21:44
  • Follow-up question. I've managed to add a "Done" button and a "Cancel" Button. However, I dont know how to make them functional? My app crashes once i click them –  Jul 12 '16 at 23:50
  • I can't help you much without knowing why it crashes. You can check the error message on xcode's console log. I suspect it's because unknown selector is called i.e. you're calling a function which is not implemented yet. These are several guide on adding button [programmatically](http://stackoverflow.com/questions/24030348/how-to-create-a-button-programmatically) and via [interface builder / storyboard](http://stackoverflow.com/questions/32572305/iboutlet-and-ibaction-in-swift) – Dickson Leonard Jul 13 '16 at 01:06
0

Use the delegate for UITextField to set all inputviews to pickerView. Make sure you set delegate for all textfields

let gradePickerView = UIPickerView()
override func viewDidLoad() {
    super.viewDidLoad()

    // set delegates for all textfields

    gradePickerView.delegate = self
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
    view.addGestureRecognizer(tap)

}

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {

    textField.inputView = gradePickerView
}
xmhafiz
  • 3,482
  • 1
  • 18
  • 26
0

I think you want to tap on 7 textfiel. Each time the pickerView will show. You picker a cell in pickerView and the textfiel(that you just tap) will show your select? If it's true. You should do fowllow this step: 1: Add tag to each textFiel: yourtextFiel.view.tag = 0 (or 1,2,3,4,...) 2: When show pickerView: Add pickerView.tag = yourtextFiel.view.tag 3: in fucion pickerView didSelectRow : get your textFiel's tag will show your selected: let mytag = pickerView.tag. Find your textFiel with "mytag" and change your text Googluck

Thành Ngô Văn
  • 142
  • 3
  • 10