Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Clean Code
- Human interface guide
- 클린 코드
- MVVM
- collectionview
- 애니메이션
- uitableview
- UICollectionView
- HIG
- uiscrollview
- rxswift
- 리펙터링
- SWIFT
- Xcode
- map
- 스위프트
- 리펙토링
- 리팩토링
- swiftUI
- ios
- tableView
- combine
- swift documentation
- Observable
- ribs
- Refactoring
- Protocol
- UITextView
- clean architecture
- RxCocoa
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] RxDataSources 스와이프하여 삭제 (swipe to delete) 적용 방법, UITableView 본문
iOS 응용 (swift)
[iOS - swift] RxDataSources 스와이프하여 삭제 (swipe to delete) 적용 방법, UITableView
jake-kim 2022. 6. 23. 22:27
사용한 프레임워크
구현 아이디어
- RxDataSources의 인스턴스가 가지고 있는 canEditRowAtIndexPath라는 프로퍼티를 사용하여 delete 기능 활성화
dataSource.canEditRowAtIndexPath = { _, _ in true }
- tableView의 rx.itemDeleted를 바인딩하여 처리
self.tableView.rx.itemDeleted
.bind { ... }
RxDataSource를 사용한 UITableView 구현
- 예제에 사용할 SectionModel
- Section의 데이터는 사용하지 않을 것이지만, section이 존재할때 어떻게 사용되는지를 예를 위해 존재
import RxDataSources
struct SomeType {
typealias Model = SectionModel<Section, Item>
enum Section: Equatable {
case date(date: Date)
}
enum Item: Equatable {
case record(title: String?)
}
}
- 예제에 사용할 ViewController
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
class ViewController: UIViewController {
}
- tableView 선언
private let tableView: UITableView = {
let view = UITableView()
view.allowsSelection = true
view.backgroundColor = .clear
view.separatorStyle = .none
view.bounces = true
view.showsVerticalScrollIndicator = true
view.contentInset = .zero
view.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
- 예제로 사용할 데이터 정의
var items = BehaviorSubject<[SomeType.Model]>(
value: [
SomeType.Model(
model: .date(date: Date()),
items: (0...100)
.map(String.init)
.map { SomeType.Model.Item.record(title: $0) }
)
]
)
- RxDataSource 인스턴스 정의
// in viewDidLoad
let dataSource = RxTableViewSectionedReloadDataSource<SomeType.Model> { dataSource, tableView, indexPath, item in
switch item {
case let .record(title):
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = title
return cell
}
}
- 데이터와 tableView의 dataSource를 바인딩
self.items
.distinctUntilChanged()
.bind(to: self.tableView.rx.items(dataSource: dataSource))
.disposed(by: self.disposeBag)
스와이프하여 삭제 구현
- 위에서 만든 dataSource 인스턴스를 사용하여 edit 기능 활성화
- 여기까지하고 스와이프하여 delete하려고 해도 동작 안하므로 주의 (rx.itemDeleted 바인딩까지 해야 활성화)
dataSource.canEditRowAtIndexPath = { _, _ in true }
- rx.itemDeleted 바인딩
- RxDataSources에서 제공하는 SectionModel은 바로 섹션 -> 아이템들에 접근이 가능
- 특정 아이템을 제거 후 onNext로 업데이트
self.tableView.rx.itemDeleted
.observe(on: MainScheduler.asyncInstance)
.withUnretained(self)
.bind { ss, indexPath in
guard var section = try? ss.items.value() else { return }
var updateSection = section[indexPath.section]
// Update item
updateSection.items.remove(at: indexPath.item)
// Update section
section[indexPath.section] = updateSection
// Emit
ss.items.onNext(section)
}
.disposed(by: self.disposeBag)
'iOS 응용 (swift)' 카테고리의 다른 글
Comments