Tunko Development Diary

RxSwift) RxCocoa - TableView 본문

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이벤트도 전달받을 수 있습니다.

반응형

'Development > RxSwift' 카테고리의 다른 글

RxSwift) RxCocoa - UICollectionView  (0) 2022.06.15
RxSwift) RxCocoa Traits(Driver)  (0) 2022.06.13
RxSwift) RxCocoa Binding  (0) 2022.06.12
RxSwift) RxCocoa 란?  (0) 2022.06.12
RxSwift) Error Handling (retry, retry(when:))  (0) 2022.06.10
Comments