前回の質問からの変化
前回の質問 リンク内容
こちらでの問題であった
最後に取得した行数が現在のtodos.countとして取得されていてdeleteされたらnumberOfRowsで整合性が保たれていないと言うエラーが出ていたので直しました。
Swift
1//todosから要素を削除して保持しておく 2 let deletedItem = self.todos.remove(at: indexPath.row) 3 4 self.allTodo.removeAll {$0 === deletedItem} 5 self.selectedTodo.removeAll {$0 === deletedItem} 6 7 //削除した結果も保存 8 let data = try! NSKeyedArchiver.archivedData(withRootObject: self.allTodo, requiringSecureCoding: false) 9 UserDefaults.standard.set(data, forKey: "todoList") 10 11 let data2 = try! NSKeyedArchiver.archivedData(withRootObject: self.selectedTodo, requiringSecureCoding: false) 12 UserDefaults.standard.set(data2, forKey: "todoShare") 13 14 tableView.deleteRows(at: [indexPath], with: .automatic) 15 16 completionHandler(true)
ソースコード
Swift5
1import UIKit 2 3class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 4 5 //registered cell 6 var todos:[Item] = [] 7 //to show in First case 8 var allTodo:[Item] = [] 9 //to show in second case 10 var selectedTodo:[Item] = [] 11 12 @IBOutlet weak var Table:UITableView! 13 14 @IBAction func segmentselected(_ sender: UISegmentedControl) { 15 16 switch sender.selectedSegmentIndex { 17 18 case 0: 19 todos = allTodo 20 case 1: 21 todos = selectedTodo 22 default: 23 fatalError("case でカバーできていません") 24 } 25 Table.reloadData() 26 } 27 28 override func viewDidLoad() { 29 super.viewDidLoad() 30 // Do any additional setup after loading the view 31 Table.delegate = self 32 Table.dataSource = self 33 34 //UD読み込み 35 if let data = UserDefaults.standard.data(forKey: "todoList"){ 36 self.allTodo = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! 37 [Item] 38 } 39 40 if let data2 = UserDefaults.standard.data(forKey: "todoShare"){ 41 self.selectedTodo = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data2) as! 42 [Item] 43 } 44 45 } 46 47 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 48 return todos.count 49 } 50 51 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 52 53 let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 54 let item = todos[indexPath.row] 55 cell.textLabel!.text = item.title 56 return cell 57 } 58 59 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 60 return view.frame.size.height/10 61 } 62 63 @IBAction func addNewTodo(_sender: Any){ 64 var textField = UITextField() 65 66 let alert = UIAlertController(title: "新しくやることを追加", message: "", preferredStyle: .alert) 67 68 let action = UIAlertAction(title: "追加", style: .default) { (action) in 69 70 let newItem:Item = Item(title: textField.text!) 71 print("追加されました") 72 73 self.allTodo.append(newItem) 74 75 //UD保存 76 let data = try! NSKeyedArchiver.archivedData(withRootObject: self.allTodo, requiringSecureCoding: false) 77 UserDefaults.standard.set(data, forKey: "todoList") 78 79 let data2 = try! NSKeyedArchiver.archivedData(withRootObject: self.selectedTodo, requiringSecureCoding: false) 80 UserDefaults.standard.set(data2, forKey: "todoShare") 81 82 //コピー 83 self.todos = self.allTodo 84 85 self.Table.reloadData() 86 } 87 88 let cancelaction = UIAlertAction(title: "キャンセル", style: .cancel) { (cancelaction) in 89 print("canceled") 90 } 91 92 alert.addTextField { (alertTextField) in 93 94 alertTextField.placeholder = "やることを記入してください" 95 textField = alertTextField 96 } 97 98 alert.addAction(action) 99 alert.addAction(cancelaction) 100 present(alert, animated: true,completion: nil) 101 102 } 103 104 //swipe action 105 func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { 106 107 // シェアのアクションを設定する 108 let shareAction = UIContextualAction(style: .normal , title: "完了") { 109 (ctxAction, view, completionHandler) in 110 print("シェアを実行する") 111 112 //add cell to second case 113 self.selectedTodo.append(self.allTodo[indexPath.row]) 114 115 //保存 116 let data2 = try! NSKeyedArchiver.archivedData(withRootObject: self.selectedTodo, requiringSecureCoding: false) 117 UserDefaults.standard.set(data2, forKey: "todoShare") 118 119 completionHandler(true) 120 self.Table.reloadData() 121 } 122 123// // シェアボタンのデザインを設定する 124// let shareImage = UIImage(systemName: "arrowshape.turn.up.right.fill")?.withTintColor(UIColor.white, renderingMode: .alwaysTemplate) 125// shareAction.image = shareImage 126 shareAction.backgroundColor = UIColor(red: 0/255, green: 125/255, blue: 255/255, alpha: 1) 127 128 // 削除のアクションを設定する 129 let deleteAction = UIContextualAction(style: .destructive, title:"削除") { 130 (ctxAction, view, completionHandler) in 131 132 //todosから要素を削除して保持しておく 133 let deletedItem = self.todos.remove(at: indexPath.row) 134 135 self.allTodo.removeAll {$0 === deletedItem} 136 self.selectedTodo.removeAll {$0 === deletedItem} 137 138 //削除した結果も保存 139 let data = try! NSKeyedArchiver.archivedData(withRootObject: self.allTodo, requiringSecureCoding: false) 140 UserDefaults.standard.set(data, forKey: "todoList") 141 let data2 = try! NSKeyedArchiver.archivedData(withRootObject: self.selectedTodo, requiringSecureCoding: false) 142 UserDefaults.standard.set(data2, forKey: "todoShare") 143 144 tableView.deleteRows(at: [indexPath], with: .automatic) 145 146 completionHandler(true) 147 } 148 149 // スワイプでの削除を無効化して設定する 150 let swipeAction = UISwipeActionsConfiguration(actions:[deleteAction, shareAction]) 151 swipeAction.performsFirstActionWithFullSwipe = false 152 153 return swipeAction 154 } 155} 156 157class Item: NSObject,NSCoding{ 158 159 var title:String 160 161 init(title:String) { 162 self.title = title 163 } 164 165 func encode(with coder: NSCoder) { 166 coder.encode(self.title,forKey: "title") 167 } 168 169 required init?(coder: NSCoder) { 170 self.title = coder.decodeObject(forKey: "title") as! String 171 } 172 173}
こちらで削除ともに完成に近いものができたと思ったのですが
問題点
case0=allTodo
case1=selectedTodo
- share(完了)を押すとselectedTodoにコピーされるのだが同時にallTodoからデータを消したい
- selectedTodoでのshareが有効になっているためselectedTodoでShareのactionを無効にすることは可能ですか?
- 2でshareが有効になっているのでselectedTodoでshareを押すとselectedTodoにrowが追加されるわけです
gyazoによる問題の動画です>> gyazo.GIF
上記の動画のようにselectedTodoで3を複製した後3(row4)を削除するとallTodoにはrow4が存在していないため?かallTodoではrow3から削除されてしまいます。
こちらはどのように改善したら良いと思われますか?
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/12 13:28