본문 바로가기
iOS/RxSwift

TableView

by 패쓰킴 2023. 3. 2.
728x90

기본적인 테이블뷰 구현 방법

RxSwift에서는 옵저버블과 테이블뷰를 바인딩 하는 방식으로 데이터를 표시해주기 때문데 테이블뷰의 datasorce와 delegate를 연결해줄 필요가 없다.

 

import UIKit
import RxSwift
import RxCocoa


class MyTableViewViewController: UIViewController {
    @IBOutlet weak var table: 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 in
//            let cell = tableView.dequeueReusableCell(withIdentifier: "standardCell")!
//            cell.textLabel?.text = element
//            return cell
//        }.disposed(by: bag)
        
        // 방법2
        // 클로저에서 셀 구성
        // 방법1보다 더 간결해짐, cellIdentifier를 통해 cell에 바로 접근
//        nameObservable.bind(to: listTableView.rx.items(cellIdentifier: "standardCell")) { row, element, cell in
//            cell.textLabel?.text = element
//        }.disposed(by: bag)
        
        // 방법3
        // 커스텀 셀에 상세정보 표시
        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)
//        // 셀 선택 액션
//        listTableView.rx.modelSelected(Product.self)
//            .subscribe(onNext: { product in
//                print(product.name)
//            }).disposed(by: bag)
//        // 셀 선택 '상태' 제거
//        listTableView.rx.itemSelected
//            .subscribe(onNext: { [weak self] indexPath in
//                self?.listTableView.deselectRow(at: indexPath, animated: true)
//            }).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)
        
        // 델리게이트를 지정하고 싶다면!
        // 코코아터치 방식으로 딜리게이트를 지정하면 RxCocoa로 구현한 코드는 동작하지 않는다.
        // #1
//        listTableView.delegate = self
        // 코코아터치 방식의 딜리게이트 동작을 rxcocoa 방식과 함께 사용할 수 있는 코드
        listTableView.rx.setDelegate(self) // setDataSource는 잘 사용하지 않음
            .disposed(by: bag)
    }
}

// #2
extension MyTableViewViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print(#function)
    }
}
728x90

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

Action  (0) 2024.01.02
Button  (0) 2023.12.21
기본  (0) 2023.11.23
distinctUntilChanged(compare: )  (2) 2023.02.20

댓글