티스토리 뷰
AViewModel과 UITableVIewDiffableDataSource 활용하기
※ 스토리보드로 진행
ViewController
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
private let viewModel = ViewModel()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
viewModel.makeTableView(tableView: tableView)
}
}
ViewModel
- custom cell일 경우, register해주는 작업도 필요
- 반드시 append 해주는 작업을 해야 dataSource로 쓸 수 있음
import UIKit
import Combine
class ViewModel {
private var dataSource: UITableViewDiffableDataSource<SectionClass, Int>!
//<Int, Int> -> Section과 row라고 생각해주면 됨, hasable한 값이 들어가야 함
let sectionClasses = [SectionClass(name: "1"), SectionClass(name: "2")]
var numbers = [1, 2, 3]
var newNumbers = [4, 5, 6]
func addNewDate() {
updateSnapshot2(items: numbers + newNumbers, section: sectionClasses[1])
}
private func updateSnapshot(items: [Int], section: SectionClass) {
var snapshot = NSDiffableDataSourceSnapshot<SectionClass, Int>()
snapshot.appendSections(sectionClasses)
snapshot.appendItems(items, toSection: section)
dataSource.apply(snapshot)
}
func makeTableView(tableView: UITableView) {
let nib = UINib(nibName: CustomTableViewCell.identifier, bundle: nil)
tableView.register(nib, forCellReuseIdentifier: CustomTableViewCell.identifier)
dataSource = .init(tableView: tableView, cellProvider: { tableView, indexPath, itemIdentifier in
guard let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier, for: indexPath) as? CustomTableViewCell else { fatalError() }
cell.configure(text: String(itemIdentifier))
return cell
})
updateSnapshot(items: numbers, section: sectionClasses[0])
}
}
struct SectionClass: Hashable {
let name: String
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
}
0. UITableViewDiffableDataSource 선언
@preconcurrency @MainActor class UITableViewDiffableDataSource<SectionIdentifierType, ItemIdentifierType> : NSObject where SectionIdentifierType : Hashable, SectionIdentifierType : Sendable, ItemIdentifierType : Hashable, ItemIdentifierType : Sendable
- UITableViewDiffableDataSource<> 안에 들어있는 type은 hasable 해야 함
- UITableViewDiffableDataSource<A, B>인 경우 -> A가 section, B가 Item이라고 생각하면 됨.
1. Section과 Item을 추가
1-1. Section을 추가하는 방법 - enum로 만들기
- enum 자체가 hasable하기 때문에 매우 유용
enum Section: CaseIterable {
case first
case second
}
- UITableViewDiffableDataSource<>안의 타입을 맞춰줘야 함 (여기서는 enum이므로 Section 타입)
//선언부
private var dataSource: UITableViewDiffableDataSource<Section, Int>!
//사용부
private func updateSnapshot(items: [Int], section: Section) {
var snapshot = NSDiffableDataSourceSnapshot<Section, Int>()
snapshot.appendSections(Section.allCases)
snapshot.appendItems([1, 2, 3], toSection: Section.first)
snapshot.appendItems([4, 5, 6], toSection: Section.second)
dataSource.apply(snapshot)
}
1-2. Section을 추가하는 방법 - struct로 만들기(현재 코드)
- struct는 hasable 하지 않기 때문에 hash 함수를 구현해줘야 하
struct SectionClass: Hashable {
let name: String
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
}
//선언부
private var dataSource: UITableViewDiffableDataSource<SectionClass, Int>!
let sectionClasses = [SectionClass(name: "1"), SectionClass(name: "2")]
//구현부
private func updateSnapshot2(items: [Int], section: SectionClass) {
var snapshot = NSDiffableDataSourceSnapshot<SectionClass, Int>()
snapshot.appendSections(sectionClasses)
snapshot.appendItems(items, toSection: section)
dataSource.apply(snapshot)
}
2. dataSource 연결
- cellProvider를 클로저로 전달할 수도 있음
dataSource = .init(tableView: tableView, cellProvider: { tableView, indexPath, itemIdentifier in
guard let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier, for: indexPath) as? CustomTableViewCell else { fatalError() }
cell.configure(text: String(itemIdentifier))
return cell
})
CustomCell
- nib 파일 통해 label 하나 넣고, 연결해놓기
import UIKit
class CustomTableViewCell: UITableViewCell {
static let identifier = String(describing: CustomTableViewCell.self)
@IBOutlet weak var label: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func configure(text: String) {
label.text = text
}
}
UITableViewDelegate
- UITableViewDiffableDataSource쓸 때, Delegate는 평소랑 똑같이 써주면 된다!
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
private let viewModel = ViewModel()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
viewModel.setupTableView(tableView: tableView)
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
viewModel.addNewDate()
}
}
//ViewModel.swift
func addNewDate() {
updateSnapshot2(items: numbers + newNumbers, section: sectionClasses[1])
}
'순진이의 하루 > study정리' 카테고리의 다른 글
20. Storyboard, nib (0) | 2022.12.12 |
---|---|
19. 쫌쫌따리 유용한 정보_2022.12.12 (0) | 2022.12.05 |
16. Preprocessor_2022.10.24 (0) | 2022.10.24 |
15. MapKit2_2022.09.26 (1) (0) | 2022.09.26 |
13. async/await_2022.09.19 (0) | 2022.09.19 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크