[Rx] UITableViewCell 밀어서 삭제
Rx ver. 이라고 제목에 써 놓으니 누가 보면 다른 버전도 있는 줄 알겠네 키키
이번 글은 사실 별 건 아니고, RxSwift로 reactive 하게 짜는 연습 중에 너무 당연하게 쓰던 코드가 안 먹어서 당황했지만
분명 나 같은 몽츙이가 혼자는 아닐 것 같아서 쓴다. 전체 코드를 보고 싶다면 일루와유.
결론부터 말하자면,
코드를 Reactive하게 잘 짜 놓았다면 알.아.서 잘 업데이트를 해주고 있다는 것. (힌트를 얻었다면 가서 고치시고, 아니라면 쭉 같이 보시죱!)
non-RX Way
기존에 tableview swipe to delete cell 을 하는 방식은 아래와 같다. (참고)
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
datasource.remove(at: indexpath.row)
tableView.deleteRows(at: [indexpath], with: .fade)
}
}
editingStyle이 delete인지 확인하고 → data source가 되는 자료구조에서 알맞게 빼고 → tableView가 다시 그릴 수 있도록 업데이트
그랬더니 문제가?
항!상! 이렇게 했는데 문제가 생기버려써.
즉 삭제를 하고 있는 이 경우, 편집 전 row 개수 = 편집 후 row 개수 + 빼는 row 개수 이어야 하는데 그게 안맞다는 것.
혼자 저걸 "...뭐래 👀" 이러고 보다가 'row 개수'에 관여하는 애는 numberOfRowsInSection 이니까 두 함수에 break point를 찍고
po list.value.count (list는 behavior relay) 를 찍어봤다. 헤헤헿 역시 내가 잘못했지
그려그려 내가 문제지
data는 빨간색 선을 따라 움직인다.
1. 외부에서 값을 받아오면 2. 뷰 모델의 imageList가 갖고 있다.
3. 뷰 모델의 imageList를 뷰컨에서 subscribe 하고 있으면서 4. 뷰컨의 변수 imageList에 복사해두는데 5. 이 변수가 tableView의 datasource.
위에 에러가 발생한 이유는 tableView.deleteRows 때문에 발생했던 것이다.
이미 datasource.remove를 하면서(물론 코드 이렇게 못씀. Rx로 작성한 코드는 밑에 둘게유) 이미 업데이트 해놨는데
거기에 row를 또 빼려는 시도를 하니까 합이 안맞는 것.
수정 코드
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// 바로 list.value.remove 를 못하는 이유는 .value는 get property라서
var imageList = list.value
imageList.remove(at: indexPath.row)
// 수정 된 목록을 viewModel의 imageList에 주면 (알아서 뷰컨의 list도 업데이트 됨)
viewModel.imageList.accept(imageList)
}
}