i made a simple apps for practice. I'm a beginner in programming.
First of all I will explained in detail what I did and what I want to do.
Create a File a Swift file for data :
class done {
var meal: [String] = ["tomato","banana","potato","peanuts"]
}
ViewController Setup I have a Textfield and a Button to go to the next page this will add the data of the textfield that the person enter and will add to my meal data list:
import UIKit
class ViewController: UIViewController {
var data = done()
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
print("Data now : \(data.meal)")
}
@IBAction func buttonaction(_ sender: UIButton) {
var newitem = textField.text ?? ""
if textField.text == "" {
newitem = "empty"
}
data.meal.append(newitem)
performSegue(withIdentifier: "toView", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toView" {
let successVCG = segue.destination as! TableViewController
successVCG.data = self.data
}
}
}
I have a second ViewController that will display in a TableView with a TableViewcell and Inside I have a Pickerview in each row..
import UIKit
class TableViewController: UIViewController{
@IBOutlet weak var table: UITableView!
var data = done()
override func viewDidLoad() {
super.viewDidLoad()
print("Transfert Data OK : \(data.meal)")
table.delegate = self
table.dataSource = self
}
@IBAction func `return`(_ sender: Any) {
print(data.meal)
}
@IBAction func update(_ sender: Any) {
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toViewa" {
let successVCG = segue.destination as! ViewController
successVCG.data = self.data
}
}
}
extension TableViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 300
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "cellule") as? TableViewCell {
return cell
}
let cell2 = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
return cell2
}
}
And it's the configuration of the TableViewCell
import UIKit
class TableViewCell: UITableViewCell {
@IBOutlet weak var picker: UIPickerView!
var data = done()
override func awakeFromNib() {
super.awakeFromNib()
picker.delegate = self
picker.dataSource = self
}
}
extension TableViewCell: UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return data.meal.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return data.meal[row]
}
}
The Picker view is display the data.meal correctly but never Updater while I add new stuff in the variable.
In my print. I see the new data update In the ViewController and the TableViewController but I try everything I could with my learning. Can't update the PickerView. I can't send the new value in the TableViewCell...mPlease help. Thank you very Much. Love to code!
This is because you don't implement the
pickerView(_:didSelectRow:inComponent:)picker view's delegate method in your table view cell. So even if the user selects a new row from your picker view, the changes simply won't get reflected in your data variable. You could implement this method and change your data model accordingly from within this method.An other thing I noticed is that you're not passing your data from the parent view to your table view cell, so the data variable in your table view cell never gets the latest data. You could simply pass the data to your cell in the
cellForRow(at:)method of your table view.Also I would recommend you to name your data model something different than
done. This name is kind of confusing (because it would usually refer to an action), and the capitalization is misleading because for example when in your code you write vardone = done()it feels like you're calling a function or a closure, while, from my understanding, you're actually initializing your data model.This is because in Swift you would name by convention all your methods, functions and variables using lower camel case (for example
let myVariable: Double = 0), and types such as structs, enums and classes in upper camel case (for examplemyData = MyDataModel()).