[RxCocoa] TableView

RudinP·2025년 11월 4일
0

Study

목록 보기
371/376

RxCocoa에서는 델리게이트 패턴을 사용하지 않고, 옵저버블을 테이블에 바인딩한다.

옵저버블을 테이블에 바인딩

items

기본셀

import UIKit
import RxSwift
import RxCocoa


class RxCocoaTableViewViewController: UIViewController {
    
    @IBOutlet weak var listTableView: UITableView!
    
    let priceFormatter: NumberFormatter = {
        let f = NumberFormatter()
        f.numberStyle = NumberFormatter.Style.currency
        f.locale = Locale(identifier: "Ko_kr")
        
        return f
    }()
    
    let bag = DisposeBag()

    let nameObservable = Observable.of(appleProducts.map { $0.name })
    
    let productObservable = Observable.of(appleProducts)
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // #1
        nameObservable.bind(to: listTableView.rx.items) { tableView, row, element //테이블뷰참조, row인덱스, 표시할 요소
            in
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "standardCell")!
            cell.textLabel?.text = element
            return cell
        }
        .disposed(by: bag)
    }
}
//# 2
nameObservable.bind(to: listTableView.rx.items(cellIdentifier: "standardCell")) { row, element, cell in
     cell.textLabel?.text = element
 }
     .disposed(by: bag)

커스텀셀

        productObservable.bind(to: listTableView.rx.items(cellIdentifier: "productCell", cellType: ProductTableViewCell.self)) { [weak self] row, element, cell in
            cell.categoryLabel.text = element.category
            cell.productNameLabel.text = element.name
            cell.summaryLabel.text = element.summary
            cell.priceLabel.text = self?.priceFormatter.string(for: element.price)
        }
        .disposed(by: bag)

셀 터치

extension에 추가된 옵저버블을 구독

indexPath 방출

        listTableView.rx.itemSelected
            .subscribe(onNext: { [weak self] indexPath in
                self?.listTableView.deselectRow(at: indexPath, animated: true)
            })
            .disposed(by: bag)

모델 자체 방출

        listTableView.rx.modelSelected(Product.self)
            .subscribe(onNext: { product in
                print(product.name)
            })
            .disposed(by: bag)

둘 다 필요

        Observable.zip(listTableView.rx.modelSelected(Product.self), listTableView.rx.itemSelected)
            .bind { [weak self] (product, indexPath) in
                self?.listTableView.deselectRow(at: indexPath, animated: true)
                print(product.name)
            }
            .disposed(by: bag)
  • 선택이벤트를 처리하면서 데이터가 필요하면 modelSelected 활용
  • 인덱스만 필요하면 itemIndex를 활용
  • itemIndex와 model 모두 필요하면 zip 연산자로 병합

델리게이트 사용법

  • RxCocoa에서도 사용할수는 있다
  • 지정 방식이 다르다
    • cocoatouch식으로 구현하면 기존 rx 구현이 무시된다
  • 두 개의 섹션을 표시하고 삭제와 이동을 구현하는 등은 rxcocoa로 하면 코드가 복잡해짐
      1. 기존 delegate 패턴 사용하기
      1. RxDataSource 사용하기
listTableView.rx.setDelegate(self)
       .disposed(by: bag)
 //이후 기존 cocoatouch 식으로 구현
profile
iOS 개발자가 되기 위한 스터디룸/스터디의 레퍼런스는 모두 kxcoding

0개의 댓글