Development/RxSwift
RxSwift) RxCocoa - TableView
Tunko
2022. 6. 14. 02:53
드디어 TableView에 대해서 블로그에 글을 남깁니다.
사실 TableView만 잘 활용해도 절반정도는 먹고 들어간다고 생각합니다. ㅎ
사설은 접고 바로 TableView대해서 남깁니다.
TableView
import UIKit
import RxSwift
import RxCocoa
struct Fruit {
let emoticon : String
let name : String
}
let fruitModel : [Fruit] = [Fruit(emoticon: "🍎", name: "사과"),
Fruit(emoticon: "🍊", name: "오랜지"),
Fruit(emoticon: "🍐", name: "배"),
Fruit(emoticon: "🥝", name: "키위"),
Fruit(emoticon: "🍓", name: "딸기")]
class TunkoTableViewController: UIViewController {
@IBOutlet var tableView: UITableView!
let dispose = DisposeBag()
let modelObservable = Observable.of(testModel.map {$0})
override func viewDidLoad() {
super.viewDidLoad()
modelObservable.bind(to: tableView.rx.items) { tableView, row, element in
let cell = tableView.dequeueReusableCell(withIdentifier: "TunkoTableViewCell") as! TunkoTableViewCell
cell.label?.text = element.emoticon + " " + element.name
cell.indexLabel?.text = "\\(row) - "
return cell
}
.disposed(by: dispose)
}
}
modelObservable는 UITableView에 표시할 데이터 옵저버블 입니다.
튜플형식으로 선언된 데이터를 of를 통해 하나씩 방출합니다.
데이터를 방출하는 옵저버블과 tableView 를 bind 해주었습니다.
위 bind 코드를 Rxcocoa를 통해서 간략화 할 수 있습니다.
modelObservable.bind(to: tableView.rx.items(cellIdentifier: "TunkoTableViewCell", cellType: TunkoTableViewCell.self)) { [weak self] row, element, cell in
cell.label?.text = element.emoticon + " " + element.name
cell.indexLabel?.text = "\\(row) - "
}
.disposed(by: dispose)
TableView cell 터치 이벤트 처리 (Modal)
tableView.rx.modelSelected(Fruit.self)
.subscribe { fruit in
print("\\(fruit.element!.emoticon) : \\(fruit.element!.name)")
}
.disposed(by: dispose)
선택한 셀에 데이터를 받을 수 있습니다.
TableView cell 터치 이벤트 처리 (Index)
tableView.rx.itemSelected
.subscribe { [weak self] indexPath in
// 셀 선택 상태 제거
self?.tableView.deselectRow(at: indexPath, animated: true)
}
.disposed(by: dispose)
선택한 셀 indexPath 를 알 수 있습니다.
TableView cell 터치 Modal, Index 동시 처리
Observable.zip(tableView.rx.modelSelected(Fruit.self), tableView.rx.itemSelected)
.bind { [weak self] (fruit, indexPath) in
self?.tableView.deselectRow(at: indexPath, animated: true)
print("\\(fruit.emoticon) : \\(fruit.name)")
}
.disposed(by: dispose)
zip연산자를 사용하여 tableView.rx.modelSelected 와 tableView.rx.itemSelected 대한 next 이벤트를 동시에 처리 했습니다.
Delegate 사용하기
Delegate 를 지정하면 Rx옵저버블은 이벤트를 받을 수 없습니다.
이벤트를 받으려면 다른방식으로 delegate를 설정해주어야 합니다.
...
tableView.rx.setDelegate(self)
.disposed(by: bag)
}
}
extension TunkoTableViewController : UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("delegate didSelectRowAt : \\(indexPath)")
}
}
이렇게 처리하면 delegate 메서드인 didSelectRowAt 에서도 응답하며 bind된 UI이벤트도 전달받을 수 있습니다.
반응형