簡體   English   中英

字典類型中 UserDefaults 保存的數組消失

[英]The array saved by UserDefaults in the dictionary type disappears

UIPickerView 中作為字典類型 UserDefaults 保存在 EventViewController 中的數組在返回 ViewController 時消失。 使用按鈕的@IBAction 保存放入UITextField 中的字符。 我想保留保存的字符串。 我不知道解決方案。 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!

放一個字典類型數組

    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 = ""

委托設置

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]
    }

實例化 UserDefaults

    let userDefaults = UserDefaults.standard
    let keyMenuDataList = "newMenu"

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

添加事件按鈕

    @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 設置

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

讓我們看看你的代碼:

menuDataList = userDefaults.dictionary(forKey: "keyMenuDataList") as? [String: [String]] ?? [:]
userDefaults.set(menuDataList, forKey: "keyMenuDataList")

您將userDefaults分配給menuDataList 但是,當您第一次從userDefaults獲取 key 的值時,它的值是 nil。 所以你的代碼是這樣的:

menuDataList = [:];
userDefaults.set([:], forKey: "keyMenuDataList")

您看, userDefaults將始終為 [:] 並且您一次又一次地清理menuDataList 這段代碼: menuDataList = userDefaults.dictionary(forKey: "keyMenuDataList") as? [String: [String]]?? [:] menuDataList = userDefaults.dictionary(forKey: "keyMenuDataList") as? [String: [String]]?? [:] menuDataList = userDefaults.dictionary(forKey: "keyMenuDataList") as? [String: [String]]?? [:]沒用,您可以將其刪除並重試。

您是否注冊了 UserDefaults 鍵?

每次再次啟動應用程序時,您都需要調用此 function。

UserDefaults.standard.register(defaults: [String : Any])

我將其移至 viewDidLoad 並解決了它。

menuDataList = userDefaults.dictionary(forKey: "keyMenuDataList") as? [String: [String]] ?? [:]
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]

        menuDataList = userDefaults.dictionary(forKey: "keyMenuDataList") as? [String: [String]] ?? [:]

    }
    @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)
                                
                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()
        
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM