포스트

3주차 과제 (4)

Lv3

Todo 삭제 기능 구현하기 키워드 : UITableView, UIButton

  • Todo 삭제하기 기능
    • Todo List에서 특정 Todo를 삭제할 수 있도록 화면과 기능을 자유롭게 구성해보세요.
    • 삭제하는 2가지 방식
      • 예시와 같이, Todo를 스와이프하여 삭제 - UITableView의 기능
      • Todo Cell에 삭제 UIButton을 구성

삭제 기능 구현하기.

우선 일반적으로 많이 쓰는 슬라이드를 통해 삭제를 해보려고한다.

눌러서 어떤 창을 통해(ex: Alert, OtherVC) 하는 방법도 있겠지만,

일단 눌러서 이벤트를 발생시키는건 Lv4에서 필요할것 같아서 슬라이드로 대체한다.

swipe Button 구현하기

왼쪽에 나올지 오른쪽에 나올지 정해야하는데

  • 왼쪽 : leading
  • 오른쪽 : trailing

오른쪽엔 이미 UISwitch가 있어서 왼쪽에 하는게 나을것같다.

그리고 여기서 사용해야하는것이. UIContextualAction 이다.

1
2
3
4
5
6
7
8
9
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        
        let deleteBtn = UIContextualAction(style: .normal, title: "Delete") { (UIContextualAction, UIView, success: @escaping (Bool) -> Void) in
                success(true)
        }
        
        deleteBtn.backgroundColor = UIColor.systemRed
        return UISwipeActionsConfiguration(actions: [deleteBtn])
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
            
            let deleteBtn = UIContextualAction(style: .normal, title: "Delete") { (UIContextualAction, UIView, success: @escaping (Bool) -> Void) in
                
                tableView.beginUpdates()
                self.lists.remove(at: indexPath.row)
                self.db.collection(Constants.collectionName).document(String(indexPath.row)).delete()
                tableView.deleteRows(at: [indexPath], with: .fade)
                tableView.endUpdates()
                success(true)
                
            }
            
            deleteBtn.backgroundColor = UIColor.systemRed
            return UISwipeActionsConfiguration(actions: [deleteBtn])
        }

이렇게 구현해주었다.

Documents 값 가져와서 변경하기.

하지만 이제 고민을 해야하는것이 생겼다.

지금까지는 내용을 삭제하지 않았기에 getID로 가져온 값이 indexPath.row 그리고 sender.tag와 같았는데 이제는 그렇지 않다.

여러 고민을 해본결과 그냥 docs 그대로 가져오기로 결정했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@objc func changeMode (sender : UISwitch) {
        guard let currentCell = tableView.cellForRow(at: IndexPath(row: sender.tag, section: 0)) as? ToDoListCell else { return }
        
        // switch를 조작했을때의 cell을 가져온다.
        if sender.isOn {
            db.collection(Constants.collectionName).whereField("id",isEqualTo: sender.tag).getDocuments { (querySnapshot, error) in
                if let e = error {
                    print(e)
                } else {
                    if let documents = querySnapshot?.documents {
                        for doc in documents {
                            let docuId = doc.documentID
                            self.db.collection(Constants.collectionName).document(docuId).setData([Constants.Fire.fireBool : sender.isOn],merge: true)
                        }
                    }
                }
            }
            currentCell.toDoLabel.attributedText = currentCell.toDoLabel.text?.strikeThrough() // 취소선
            lists[sender.tag].isComplete = sender.isOn // DB를 로컬에 저장한 lists에도 반영
        } else {
            db.collection(Constants.collectionName).whereField("id",isEqualTo: sender.tag).getDocuments { (querySnapshot, error) in
                if let e = error {
                    print(e)
                } else {
                    if let documents = querySnapshot?.documents {
                        for doc in documents {
                            let docuId = doc.documentID
                            self.db.collection(Constants.collectionName).document(docuId).setData([Constants.Fire.fireBool : sender.isOn],merge: true)
                        }
                    }
                }
            }
            currentCell.toDoLabel.attributedText = currentCell.toDoLabel.text?.removeStrike()
            lists[sender.tag].isComplete = sender.isOn
        }
        
    }

상당히 내용이 길어졌지만.

매커니즘은 uiswitch을 조작했을때의 그 행에 대한 값을 가져와서 그 행에대한 documents ID를 얻어오는 방식으로 했다.

작동이 잘되니 만족.

제대로 DB와 통신을 하고 있다.

어떻게 해야하나 고민을 하다가 갑자기 아이디어가 떠올랐다

너무 해당 값을 의식 했던것같다.

어차피 우리가 데이터를 가져오면 lists에 담기때문에, 거기에 담긴 id값을 반환하면 되는 해결되는 부분이었다.

잘된다.

Lv3 까지 완료.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.