The array saved in UIPickerView as a dictionary type UserDefaults in EventViewController disappears when it returns to ViewController.
Save the character put in UITextField with @IBAction of Button.
I want to keep the saved string.
I don’t know the solution.
Xcode 12.2
class EventViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
@IBOutlet weak var partsPickerView: UIPickerView!
@IBOutlet weak var partsLabel: UILabel!
@IBOutlet weak var menuPickerView: UIPickerView!
@IBOutlet weak var menuLabel: UILabel!
@IBOutlet weak var menuTextField: UITextField!
Put a dictionary type array
var menuDataList: [String: [String]] = [
"Leg": ["Squat","Leg press","Leg extension"],
"Back": ["Deadlift","Bent over row","Chinning"],
"Chest": ["Barbell bench press","Dumbbell bench press","Incline Dumbbell Bench Press"]
]
var partsDataList: [String] = [
"Leg","Back","Chest"
]
var selectedParts = ""
Delegate settings
override func viewDidLoad() {
super.viewDidLoad()
partsPickerView.delegate = self
partsPickerView.dataSource = self
menuPickerView.delegate = self
menuPickerView.dataSource = self
menuTextField.delegate = self
partsPickerView.tag = 1
menuPickerView.tag = 2
selectedParts = partsDataList[0]
}
Instantiate UserDefaults
let userDefaults = UserDefaults.standard
let keyMenuDataList = "newMenu"
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
Add event button
@IBAction func didTapAddMenuButton(_ sender: Any) {
if (menuTextField.text?.isEmpty ?? true == false) {
let okAlert = UIAlertController(title: "保存されました。", message: "", preferredStyle: .alert)
let closeAction = UIAlertAction(title: "閉じる", style: .default) { (action: UIAlertAction) in }
okAlert.addAction(closeAction)
present(okAlert, animated: true, completion: nil)
if let text = menuTextField.text {
menuDataList[selectedParts]?.append(text)
menuDataList = userDefaults.dictionary(forKey: "keyMenuDataList") as? [String: [String]] ?? [:]
userDefaults.set(menuDataList, forKey: "keyMenuDataList")
}
} else {
let ngAlert = UIAlertController(title: "テキストが空です。", message: "", preferredStyle: .alert)
let closeAction = UIAlertAction(title: "閉じる", style: .default) { (action: UIAlertAction) in }
ngAlert.addAction(closeAction)
present(ngAlert, animated: true, completion: nil)
}
menuPickerView.reloadAllComponents()
}
UIPickerView settings
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView,
numberOfRowsInComponent component: Int) -> Int {
if pickerView.tag == 1{
return partsDataList.count
} else if pickerView.tag == 2{
return menuDataList[selectedParts]?.count ?? 0
} else {
return 0
}
}
func pickerView(_ picker: UIPickerView,
titleForRow row: Int,
forComponent component: Int) -> String? {
if picker.tag == 1 {
return partsDataList[row]
} else if picker.tag == 2 {
return menuDataList[selectedParts]?[row] ?? ""
} else {
return ""
}
}
func pickerView(_ pickerView: UIPickerView,
didSelectRow row: Int,
inComponent component: Int) {
if pickerView.tag == 1 {
partsLabel.text = partsDataList[row]
selectedParts = partsDataList[row]
menuPickerView.reloadAllComponents()
} else if pickerView.tag == 2 {
menuLabel.text = menuDataList[selectedParts]?[row] ?? ""
} else {
return
}
}
3
Answers
I moved this to viewDidLoad and solved it.
Let’s see your code:
You assigned the
userDefaults
tomenuDataList
. But when you first get value for key fromuserDefaults
, it’s value is a nil. So your code is like:Your see, the
userDefaults
will always be [:] and you clean themenuDataList
again and again.This code:
menuDataList = userDefaults.dictionary(forKey: "keyMenuDataList") as? [String: [String]] ?? [:]
is useless, you can just remove it and try again.Did you register the UserDefaults keys?
You need to call this function on every time you launch your app again.