I have a Swift file containing four separate arrays of tuples. In ViewControllerA I have four different buttons, each of which changes the value of "selectedPosition" and is set to trigger "SegueAtoB". "selectedPosition" should then be used in ViewControllerB to select the appropriate array to populate a UIPickerView on ViewControllerB.
Currently, my prepare for segue method only passes the correct data the second time a button is pressed, e.g. when the app loads into ViewControllerA I press a button, it takes me to ViewControllerB, but the array selected for the UIPickerView is the default, when I dismiss back to ViewControllerA and press a button, the code works as it should.
ViewControllerA :
class ViewControllerA: UIViewController {
// Variable to hold position selected (passed through to ViewControllerB)
var selectedPosition : String = ""
// Button1
// Set up to run "SegueAtoB"
@IBOutlet weak var selectButton_CEO: UIButton!
@IBAction func selectButton_CEO_Tapped(_ sender: UIButton) {
selectedPosition = "CEO"
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SegueAtoB" {
let VC : ViewControllerB = segue.destination as! ViewControllerB
VC.ReceivePlayerDataDelegate = self
VC.currentPosition = selectedPosition
}
}
}
ViewControllerB :
class ViewControllerB: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
// set the position passed through from ViewControllerB
var currentPosition : String = ""
// set the playersArray by position
var posArray = ceoArray
// Button to dismiss ViewControllerB
@IBAction func closeButton(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
// Picker view
@IBOutlet weak var posPickerView: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
// select appropriate array based on position selected
selectArray(currentPos: currentPosition)
// Delegate picker view to self
posPickerView.delegate = self
posPickerView.dataSource = self
}
// UIPickerViewMethods
// Set the number of picker columns to 1
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
// Set the number of picker rows to the number of items in posArray
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return posArray
}
// Set the title of each picker row to each name in posArray
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return posArray[row].name
}
// Picker action
// What happens when selection is made
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(posArray[row])
// I've removed what's in here as it's not relevant to the question
}
// Method to select correct array based on currentPosition -- called in viewDidLoad
func selectArray(currentPos: String) {
switch (currentPos) {
case "CEO" :
posArray = ceoArray
case "CFO" :
posArray = cfoArray
default :
posArray = ceoArray
}
}
}
I need the UIPickerView to be updated to the relevant array on the first segue from ViewControllerA to ViewControllerB, not resorting to default on the first segue.
If multiple controls result in the same segue, you need to check the sender
in the prepare(for:)
function. If it was the CEO
button, set the CEO
string etc.:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "SegueAtoB",
let vc = segue.destination as? ViewControllerB,
let senderButton = sender as? UIButton else { return }
vc.ReceivePlayerDataDelegate = self
if (senderButton === selectButton_CEO) {
vc.currentPosition = "CEO"
} else if (senderButton === selectButton_CFO) {
vc.currentPosition = "CFO"
} // and so on
}