Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 스위프트
- map
- UITextView
- Protocol
- Refactoring
- ribs
- uiscrollview
- rxswift
- ios
- combine
- Human interface guide
- collectionview
- swift documentation
- 애니메이션
- 리팩토링
- 리펙터링
- 리펙토링
- MVVM
- Clean Code
- UICollectionView
- SWIFT
- Observable
- HIG
- swiftUI
- uitableview
- 클린 코드
- clean architecture
- Xcode
- tableView
- RxCocoa
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] UITableView Multiple Cell (다중 셀) 처리 방법 (다중 Section vs 단일 Section) 본문
iOS 응용 (swift)
[iOS - swift] UITableView Multiple Cell (다중 셀) 처리 방법 (다중 Section vs 단일 Section)
jake-kim 2022. 3. 6. 15:23
Section을 사용하는 기준
- 분류 - TableView / Section / Cell
- -> Cell들은 서로 연관되어 있는지? 연관이 적으면 Section으로 나누기
- -> Section들은 표현하려는 방향이 같은지? 표현하려는 방향이 같으면 하나의 TableView에 표현
Section을 한 개만 사용 vs Section을 여러개 사용
- 아래처럼 아이폰에 설치되어 있는 Setting앱을 보면, 하나의 TableView안에 Section이 여러개로 나누어져 있는 패턴
- Section의 개념?
- Section은 하나의 TableView 안에서 데이터의 성격을 분류할 때 사용하는 것
- Cell은 같은것을 쓸지라도 성격에 따라 Section을 나누어서 사용할 것 (Cell만 적용하다가 Cell끼리의 성격이 달라진다 싶으면 바로 Section으로 나눌 것)
- Section을 나누는것에 집중할때, 확장성에 이점이 존재
- 위 처럼 성격이 다른 아이템 간 거리 간격을 띄워달라는 기획 요청사항이 생긴 경우 -> 애초부터 Section을 여러개로 쪼개어 개발된 것이 손쉽게 수정 가능
Section을 한 개만 사용하여 다중 셀 구현 방법
- Model 정의
- 1-section, n-cell을 사용할 땐 모델쪽에서 Mode같은것을 두어서 Cell을 구분
- 아래처럼 enum으로 구분도 가능
// OnlyCellModel.swift
enum OnlyCellModel {
case profile(profileImage: UIImage?, titleText: String, descriptionText: String)
case option(iconImage: UIImage?, title: String)
case title(title: String)
}
- 사용할 Cell 세 가지 준비
- ViewController - TableView에 Cell 등록, dataSource 선언
// ViewController.swift
private let settingTableView = UITableView(frame: .zero, style: .insetGrouped).then {
$0.register(ProfileCell.self, forCellReuseIdentifier: ProfileCell.id)
$0.register(TitleCell.self, forCellReuseIdentifier: TitleCell.id)
$0.register(OptionCell.self, forCellReuseIdentifier: OptionCell.id)
$0.separatorStyle = .none
}
private var dataSource = [OnlyCellModel]()
- ViewControlelr - data 로드
private func refresh() {
self.dataSource = [
.profile(
profileImage: UIImage(named: "person"),
titleText: "Jake Kim",
descriptionText: "Apple ID, iCloud, 미디어 및 구입"
),
.title(title: "iPhone 설정 마저 하기"),
.option(iconImage: UIImage(systemName: "pencil.fill"), title: "수정하기"),
.option(iconImage: UIImage(systemName: "square.and.arrow.up.fill"), title: "공유"),
.option(iconImage: UIImage(systemName: "paperplane.fill"), title: "네비게이션")
]
self.settingTableView.reloadData()
}
- ViewController - dataSource
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
self.dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch self.dataSource[indexPath.row] {
case let .profile(profileImage, titleText, descriptionText):
let cell = tableView.dequeueReusableCell(withIdentifier: ProfileCell.id, for: indexPath) as! ProfileCell
cell.prepare(profileImage: profileImage, titleText: titleText, supplementText: descriptionText)
return cell
case let .title(title):
let cell = tableView.dequeueReusableCell(withIdentifier: TitleCell.id, for: indexPath) as! TitleCell
cell.prepare(titleText: title)
return cell
case let .option(iconImage, title):
let cell = tableView.dequeueReusableCell(withIdentifier: OptionCell.id, for: indexPath) as! OptionCell
cell.prepare(icon: iconImage, titleText: title)
return cell
}
}
}
* 1-section, n-cell 전체 코드: https://github.com/JK0369/ExTableViewMultiSection
Section을 여러개 사용하여 구현 방법
- Section을 여러개 사용할 것이기 때문에 enum으로 Section 정의
- associated-type으로 Cell의 데이터형을 배열로 정의 (Cell이 여러개이므로 배열로 정의)
// SettingSection.swift
enum SettingSection {
case profile([ProfileModel])
case option([OptionModel])
case title([TitleModel])
}
struct ProfileModel {
let profileImage: UIImage?
let titleText: String?
let descriptionText: String?
}
struct OptionModel {
let iconImage: UIImage?
let title: String?
}
struct TitleModel {
let title: String?
}
- ViewController - 데이터 로드
private func refresh() {
// profile
let profileModel = ProfileModel(
profileImage: UIImage(named: "person"),
titleText: "Jake Kim",
descriptionText: "Apple ID, iCloud, 미디어 및 구입"
)
let profileSection = SettingSection.profile([profileModel])
// title
let titleModel = TitleModel(title: "iPhone 설정 마저 하기")
let titleSection = SettingSection.title([titleModel])
// option
let optionModels = [
OptionModel(iconImage: UIImage(systemName: "pencil"), title: "수정하기"),
OptionModel(iconImage: UIImage(systemName: "square.and.arrow.up.fill"), title: "공유"),
OptionModel(iconImage: UIImage(systemName: "paperplane.fill"), title: "네비게이션")
]
let optionSection = SettingSection.option(optionModels)
self.dataSource = [profileSection, titleSection, optionSection]
self.settingTableView.reloadData()
}
- ViewController - dataSource
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
self.dataSource.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch self.dataSource[section] {
case let .profile(profileModels):
return profileModels.count
case let .title(titleModels):
return titleModels.count
case let .option(optionModels):
return optionModels.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch self.dataSource[indexPath.section] {
case let .profile(profileModels):
let cell = tableView.dequeueReusableCell(withIdentifier: ProfileCell.id, for: indexPath) as! ProfileCell
let profileModel = profileModels[indexPath.row]
cell.prepare(
profileImage: profileModel.profileImage,
titleText: profileModel.titleText,
supplementText: profileModel.descriptionText
)
return cell
case let .title(titleModels):
let cell = tableView.dequeueReusableCell(withIdentifier: TitleCell.id, for: indexPath) as! TitleCell
let titleModel = titleModels[indexPath.row]
cell.prepare(titleText: titleModel.title)
return cell
case let .option(optionModels):
let cell = tableView.dequeueReusableCell(withIdentifier: OptionCell.id, for: indexPath) as! OptionCell
let optionModel = optionModels[indexPath.row]
cell.prepare(
icon: optionModel.iconImage,
titleText: optionModel.title
)
return cell
}
}
}
* n-section, n-cell 전체 코드: https://github.com/JK0369/ExTableViewMultiSection/tree/MultiSection
번외) Section 스타일
* 이전 포스팅 글 참고: https://ios-development.tistory.com/538
'iOS 응용 (swift)' 카테고리의 다른 글
Comments