72073


TodoListアプリを作っています。  
リストからタスクをスワイプして削除した後、新しくタスクを追加すると削除したタスクが元に戻ってしまいます。  
削除したままの状態にしたいのですが、どうしたら良いのでしょうか。。  
回答いただけたら幸いです。  
mac 10.15.7  
xcode 12.1

[code]

    import UIKit
    
    class ViewController: UIViewController {
        
        @IBOutlet var tableView: UITableView!
        var tasks = [String]()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            self.title = "リスト"
            
            tableView.delegate = self
            tableView.dataSource = self
            
            if !UserDefaults().bool(forKey: "setup") {
                UserDefaults().set(true, forKey: "setup")
                UserDefaults().set(0, forKey: "count")
            }
            updateTasks()
        }
        
        func updateTasks() {
            
            tasks.removeAll()
            
            guard let count = UserDefaults().value(forKey: "count") as? Int else {
                return
            }
            
            for x in 0..<count {
    
                if let task = UserDefaults().value(forKey: "task_\(x+1)") as? String {
                    tasks.append(task)
                }
            }
            tableView.reloadData()
        }
        
        @IBAction func didTapAdd() {
            
            let vc = storyboard?.instantiateViewController(identifier: "entry") as! EntryViewController
            vc.title = "リストに追加"
            vc.update = {
                //非同期処理　更新を優先
                DispatchQueue.main.async {
                    self.updateTasks()
                }
            }
            navigationController?.pushViewController(vc, animated: true)
        }
    }
    
    extension ViewController: UITableViewDelegate {
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            tableView.deselectRow(at: indexPath, animated: true)
            
            let vc = storyboard?.instantiateViewController(identifier: "task") as! TaskViewController
            vc.title = "リストに追加"
            vc.task = tasks[indexPath.row]
            navigationController?.pushViewController(vc, animated: true)
        }
    }
    
    extension ViewController: UITableViewDataSource {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return tasks.count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = tasks[indexPath.row]
            return cell
        }
        
        //タスクを削除
        func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
            let index = indexPath.row
            tasks.remove(at: index)
            let userDefaults = UserDefaults.standard
            userDefaults.set(tasks, forKey: "tasks")
            userDefaults.removeObject(forKey: "tasks")
            tableView.reloadData()
        }
    }
    
[/code]

[code]

    import UIKit
    
    class EntryViewController: UIViewController, UITextFieldDelegate {
        
        @IBOutlet var field: UITextField!
        var update: (() -> Void)?
        
        override func viewDidLoad() {
            super.viewDidLoad()
            field.delegate = self
            navigationItem.rightBarButtonItem = UIBarButtonItem(title: "保存", style: .done, target: self, action: #selector(saveTask))
        }
        
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            saveTask()
            return true
        }
        
        @objc func saveTask() {
            guard let text = field.text, !text.isEmpty else {
                return
            }
            guard let count = UserDefaults().value(forKey: "count") as? Int else {
                return
            }
            let newCount = count + 1
            UserDefaults().set(newCount, forKey: "count")
            UserDefaults().set(text, forKey: "task_\(newCount)")
            update?()
            navigationController?.popViewController(animated: true)
        }
    }
    
[/code]


CC BY-SA 4.0
2020-11-08T09:57:08.620
71800
2020-11-19T11:33:36.900
42090
question
swift ios xcode
削除したリストが元に戻る


`UserDefaults`のキーに`"tasks"`が使われているのは『タスクを削除』担当の`tableView(_:editingStyleForRowAt:)`内だけで、ほかでは`"task_\(x)"`を使ってデータの保存と読み出しがされているようです。

コードそのものには問題はなさそうなので、キーを`"tasks"`に絞ってやるとうまくいくはずです。

あと`tableView(_:editingStyleForRowAt:)`では
`UserDefaults.standard`が使われていますが、ほかは`UserDefaults()`になっているので、特別な理由がなければ`standard`で統一されたほうがいいと思います。

<https://developer.apple.com/documentation/foundation/userdefaults/1416603-standard>


CC BY-SA 4.0
2020-11-19T11:33:36.900
72073
2020-11-19T11:33:36.900
27078
71800
answer