오늘은 가장 많이 사용하고 기본이 되는 TableView, CollectionView를 이전에 Delegate , DataSource를 사용해서 구현하는 것이 아닌 RxSwift를 사용해서 구현하는 것을 해보았다 ㅎㅎ
이전에 RxSwift를 사용하지 않고 구현하던 방식과 RxSwift를 사용하는 방식을 비교하면서 구현해보니 슬슬 RxSwift를 활용해서 구현하는 방식이 감이 오는 것 같다 :)
하나하나 살펴보자!
TableVIew
먼저 테이블 뷰를 구성할 더미 데이터를 만들어 주었다.
struct Product {
let imageName: String
let title: String
}
그 다음 데이터를 보내 줄 ViewModel를 구현한다.
struct ProductViewModel {
var items = PublishSubject<[Product]>()
func fetchItem() {
let products = [
Product(imageName: "house", title: "Home1"),
Product(imageName: "gear", title: "Home2"),
Product(imageName: "person.circle", title: "Home3"),
Product(imageName: "airplane", title: "Home4"),
Product(imageName: "bell", title: "Home5")
]
items.onNext(products)
items.onCompleted()
}
}
items를 PublishSubject를 가지도록 구현한다 그 이후 onNext를 통해 만들어 둔 더미 데이터를 전달할 수 있도록 하고 onCompleted를 통해 해당 내용을 완료하는 이벤트를 발생시킨다.
class ViewController: UIViewController {
let tableView: UITableView = {
let table = UITableView()
table.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
return table
}()
let viewModel = ProductViewModel()
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
tableView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
fetchTableView()
}
func bindTableData() {
viewModel.items.bind(to: tableView.rx.items(cellIdentifier: "cell", cellType: UITableViewCell.self)) { row, product, cell in
cell.textLabel?.text = product.title
cell.imageView?.image = UIImage(systemName: product.imageName)
}.disposed(by: disposeBag)
tableView.rx.modelSelected(Product.self).bind { product in
print(product.title)
}.disposed(by: disposeBag)
viewModel.fetchItem()
}
}
그 다음 VC를 통해 뷰모델의 값을 가질 수 있도록 만들고 disposeBag도 담아서 바로 사용할 수 있도록 구현해 주었다.
그 이후 tableview를 선언해주고 오토레이아웃을 잡아주는 과정은 생략하도록 하겠다 🙂
중요한 부분은 바로
func bindTableData() {
viewModel.items.bind(to: tableView.rx.items(cellIdentifier: "cell", cellType: UITableViewCell.self)) { row, product, cell in
cell.textLabel?.text = product.title
cell.imageView?.image = UIImage(systemName: product.imageName)
}.disposed(by: disposeBag)
tableView.rx.modelSelected(Product.self).bind { product in
print(product.title)
}.disposed(by: disposeBag)
viewModel.fetchItem()
}
이전에 RxSwift를 사용하지 않는다면 Delegate, DataSource를 활용해 셀에 데이터 갯수를 설정하고 데이터를 넣어주는 과정으로 구현했다면
RxSwift를 통해 반응형으로 업데이트 내용을 바로바로 넣어줄 수 있도록 구현할 수 있다.
위 내용은 3가지가 구현되어있는데 첫번째로 데이터를 셀에 넣어주는 로직과 셀을 선택했을때 나오는 이벤트 로직, 그리고 데이터를 패치하는 메서드를 넣어 구현하였다.
이 과정을 통해 RxSwift에서 .bind .modelSelected를 이해하고 사용할 수 있을 것 같다.
CollectionView
이전 과정은 TableView와 동일하니 생략하기로 한다 ㅎㅎ 사실 앞에 RxSwift를 적용하는 과정도 동일하게 진행되지만 그래도 기록을 남겨보도록 하자
import UIKit
import RxSwift
import RxCocoa
class ItemViewController: UIViewController {
let viewModel = ItemsViewModel()
let disposeBag = DisposeBag()
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: 100, height: 100)
layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
layout.minimumInteritemSpacing = 16
layout.minimumLineSpacing = 16
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.register(ItemCollectionViewCell.self, forCellWithReuseIdentifier: ItemCollectionViewCell.identifier)
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
fetchCollectionView()
}
func setupUI() {
view.addSubview(collectionView)
collectionView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
}
func bindCollectionData() {
viewModel.item.bind(to: collectionView.rx.items(cellIdentifier: ItemCollectionViewCell.identifier, cellType: ItemCollectionViewCell.self)) { row, item, cell in
cell.titleLabel.text = item.title
cell.imageView.image = UIImage(systemName: item.imageName)
}.disposed(by: disposeBag)
collectionView.rx.modelSelected(Items.self).bind { item in
print(item.title)
}.disposed(by: disposeBag)
viewModel.fetchItem()
}
}
여기서 테이블 뷰와 다른점은 FlowLayout을 적용한 부분 정도? 다시 한번 코드를 확인해보면서 데이터를 바인딩하는 부분에 익숙해지고 자연스럽게 RxSwift를 사용할 수 있도록 연습 또 연습하자!
'◽️ Programming > RxSwift' 카테고리의 다른 글
RxSwift에서 Driver란 무엇일까 (0) | 2024.08.26 |
---|---|
[RxSwift] 가장 기본적이고 중요한 Observable에 대해서 알아보자 (0) | 2024.08.20 |
API 네트워크 통신 과정을 통해 RxSwift 이해하기 (0) | 2024.07.28 |
[SwiftUI,RxSwift] 데이터 모델링, 메인 UI 그리기 , DisposeBag , onNext , onAppear (0) | 2024.07.05 |
RxSwift에 대해서 알아보자 (0) | 2024.05.25 |