: ๋ด๋ถ์ ์ ์ด ์กด์ฌํ๊ณ ์ธ๋ก๋ก๋ง ์คํฌ๋กค์ด ๊ฐ๋ฅํ ๋ทฐ
๊ทธ๋ฃน์ ์ง์ ์๋ ์์
๋ธ๋ฆฌ๊ฒ์ดํธ ํจํด๊ณผ ํจ๊ปํ๋ ๊ฐ๋
ViewController(๊ฐ์ฒด)
tableView(๊ฐ์ฒด)
tableViewCell(๊ฐ์ฒด)
ViewController์ tableView ๊ฐ์ ์๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ์์ฌ์ํต ํ์ํ๋ฐ
์ด๊ฒ์ ๋ธ๋ฆฌ๊ฒ์ดํธ ํจํด์ผ๋ก ๊ตฌ์ฑํ๋ค.
UITableVivewController๋ฅผ ์ฌ์ฉํ ๋๋ UITableViewDatSource ํ๋กํ ์ฝ์ ์ฑํํด์ค์ผ ํ๋ค.
์ด ํ๋กํ ์ฝ์ tableView์ ViewController๊ฐ ํต์ ํ ์ ์๊ฒ ํด์ฃผ๋ ์ญํ ์ ํ๋ค.
์ปจํ ์ธ ์ ๋ํ ๋ฐ์ดํฐ๋ค์ ํ์ํ ๊ฑด์ง์ ๋ํ ์ํต. ์ ์ ๋ช๊ฐ ํ์ํ์ง, ์ ์ ์ด๋ป๊ฒ ํ์ํด์ผํ๋์ง
1. UITableView ์ ์ธ ๋ฐ ์์ฑ
2. delegate์ dataSource ํ๋กํ ์ฝ ์ฑํ
// UITableView ์ธ์คํด์ค ์ ์ธ
var tableView: UITableView = {
// UITableView ์ธ์คํด์ค ์ด๊ธฐํ ๋ฐ ์ค์
let tableView = UITableView()
tableView.delegate = self //tableView์ ์ฌ๋ฌ๊ฐ์ง ์์ฑ ์ธํ
์ ํด๋น ๋ทฐ์ปจ์์ ๋์ ์ธํ
tableView.dataSource = self //tableView ์์ ์ง์ด ๋ฃ์ ๋ฐ์ดํฐ๋ค์ ํด๋จ ๋ทฐ์ปจ์์ ์ธํ
tableView.register(CustumTableViewCell.self, forCellReuseIdentifier: CustumTableViewCell.id)
return tableView
}
3-1. UITableViewDataSource ํ๋กํ ์ฝ์ ํ์ ๋ฉ์๋ ๊ตฌํ
ํ๋กํ ์ฝ์ ์ฑํํ๊ธฐ ์ํด์๋ ํด๋์ค ํ๋จ์ extension์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ๋ ์ฑ์ด ์ข๋ค.
tableView(_:numberOfRowsInSection:)์ tableView(_:cellForRowAt:)
extension ViewController: UITableViewDataSource { // ์ฑ
์์ ๋ทฐ์ปจ์ ์์
// ํ
์ด๋ธ๋ทฐ ์น์
๋ด ํ์ ๊ฐ์ ๋ฐํ
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10 // ์์๋ก 10๊ฐ์ ํ์ ๋ฐํ
}
// ๊ฐ ํ์ ํ์ํ ์
๋ฐํ
// indexPath = ํ
์ด๋ธ๋ทฐ์ ํ๊ณผ ์น์
์ ์๋ฏธ
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: CustumTableViewCell.id) as? TableViewCell else { return }
cell.configureCell()
return cell
}
}
identifier๋ ๊ฐ Cell์ ํด๋์ค๋ช ๊ณผ ๋์ผํ๊ฒ ํ๋ ๊ฒ์ด ์์ ํ ๋ ํธํ๋ค!!
3-2. UITableViewDelegate ํ๋กํ ์ฝ์ ๋ฉ์๋๋ ์ ํ ์ฌํญ
์ ์ ํ, ์ ๋์ด ์ค์ , ์ค ํธ์ง, ์น์ ํค๋ ๋ฐ ํธํฐ์ ๋ทฐ ์ปจ์คํฐ๋ง์ด์ง ๋ฑ ์ฃผ๋ก ํ ์ด๋ธ๋ทฐ ๋์์ ์ฌ์ฉ์ ์ ์ํ๋ค.
extension ViewController: UITableViewDelegate { // ์ฑ
์์ ๋ทฐ์ปจ์ ์์
// ํ
์ด๋ธ๋ทฐ ์น์
๋ด ํ์ ๊ฐ์ ๋ฐํ// ๊ฐ ํ์ ๋์ด๋ฅผ ์ค์
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 44.0 // ์ํ๋ ๋์ด
}
}
// ์
์ด ์ ํ๋์์ ๋ ํธ์ถ
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// ์
์ ํ ์ ์คํํ ์ฝ๋๋ฅผ ์ฌ๊ธฐ์ ์์ฑ
}
// ์
์ ํ์ด ํด์ ๋์์ ๋ ํธ์ถ
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
// ์
์ ํ ํด์ ์ ์คํํ ์ฝ๋๋ฅผ ์ฌ๊ธฐ์ ์์ฑ
}
// ์น์
ํค๋ ๋ทฐ๋ฅผ ๋ฐํ
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
// ํค๋ ๋ทฐ ์ปค์คํฐ๋ง์ด์ง
return headerView
}
// ์น์
ํธํฐ ๋ทฐ๋ฅผ ๋ฐํ
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView()
// ํธํฐ ๋ทฐ ์ปค์คํฐ๋ง์ด์ง
return footerView
}
// ์น์
ํค๋์ ๋์ด๋ฅผ ์ค์
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 20.0
}
// ์น์
ํธํฐ์ ๋์ด๋ฅผ ์ค์
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 20.0
}
// ์
์ ํธ์งํ ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๋ฐํ
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
// ์
์ด ํธ์ง ๋ชจ๋๋ก ๋ค์ด๊ฐ์ ๋ ํธ์ถ
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// ์
์ญ์ ์ ์คํํ ์ฝ๋
}
}
4. TableViewCell ํด๋์ค ์ ์
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
import UIKit
//ํ
์ด๋ธ๋ทฐ ์
ํด๋์ค ์ ์
class CustomTableViewCell: UITableViewCell {
static let id = "cellID"
let customLabel: UILabel = {
let label = UILabel()
label.backgroundColor = .black
label.textColor = .white
return label
}()
//ํ
์ด๋ธ๋ทฐ์ Style๊ณผ id๋ก ์ด๊ธฐํํ ๋ ์ฌ์ฉํ๋ ์ฝ๋
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
configureUI()
}
//์ธํฐํ์ด์ค ๋น๋๋ฅผ ํตํด ์
์ ์ด๊ธฐํํ ๋ ์ฌ์ฉํ๋ ์ฝ๋
//fatalError๋ฅผ ํตํด ๋ช
์์ ์ผ๋ก ์ธํฐํ์ด์ค ๋น๋๋ก ์ด๊ธฐํํ์ง ์์์ ๋ช
์
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configureUI(){
//UIViewController๋ ๊ธฐ๋ณธ์ ์ผ๋ก view๋ฅผ, TableViewCell๋ contentView๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ๊ณ ์๋ค.
contentView.backgroundColor = .black
contentView.addSubview(customLabel)
//์์ธ ์คํ ๋ ์ด์์ ์์ฑ
}
//์
์ ์ค์ ํด์ฃผ๋ ์ธ๋ถ์์ ์ฌ์ฉํ๋ ๋ฉ์๋
public func configureCell(){
}
}
import UIKit
import SnapKit
//MakeCell ํด๋์ค: ํ
์ด๋ธ๋ทฐ์
ํด๋์ค
class MakeCell: UITableViewCell {
let contentLabel = UILabel()
//์
์ ์ด๊ธฐํ ๋ฉ์๋
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(contentLabel)
contentLabel.snp.makeConstraints {
$0.edges.equalToSuperview().inset(10)
}
}
/*
UITableViewCell์ ์์๋ฐ๋ ํด๋์ค์์ ์ฌ์ฉํ๋ ์ด๊ธฐํ ๋ฉ์๋๋
ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ํธ์ถ๋๋ ๋ฉ์๋๋ก, ๋ ๊ฐ์ง ํํ๊ฐ ์๋ค.
1. ์ฝ๋๋ก ์ด๊ธฐํํ๋ ๊ฒฝ์ฐ (init(style:reuseIdentifier:))
2. ์คํ ๋ฆฌ๋ณด๋ ๋๋ XIB ํ์ผ๋ก ์ด๊ธฐํํ๋ ๊ฒฝ์ฐ (init(coder:))
*/
//init(coder:)๋ ์คํ ๋ฆฌ๋ณด๋๋ XIB ํ์ผ๋ก ์
์ ์ด๊ธฐํํ ๋ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์
//์ฌ๊ธฐ์๋ ์ฌ์ฉํ์ง ์์ fatalError๋ฅผ ๋ฐ์์์ผ ์ฌ์ฉํ์ง ์์์ ๋ช
์
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//์
์ ๋ค์ด๊ฐ ๋ด์ฉ
func configure(){
contentLabel.text = "Sample Text"
}
}
//ViewController ํด๋์ค
class ViewController: UIViewController, UITableViewDataSource {
//ํ
์ด๋ธ๋ทฐ ์ธ์คํด์ค ์์ฑ
private let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
//ํ
์ด๋ธ๋ทฐ์ ์์ฑ์ dataSource๊ฐ ์์
//์ฌ๊ธฐ์ self๋ ViewController์ ์ธ์คํด์ค -> ์ด ํ
์ด๋ธ๋ทฐ์ ๋๋ฆฌ์๊ฐ ๋ทฐ์ปจํธ๋กค๋ฌ๊ฐ ๋๋ค๋ ์๋ฏธ
tableView.dataSource = self //UITableViewDataSource๋ฅผ ์ฑํํ๊ธฐ ๋๋ฌธ์ dataSource์ self๋ฅผ ํ ๋น(๋ธ๋ฆฌ๊ฒ์ดํธ์ ๋น์ท) -> ํ
์ด๋ธ๋ทฐ ์
์ ๋ช๊ฐ์ ์
์ด๋ป๊ฒ ๊ตฌ์ฑํ ๊ฑด์ง์ ๋ํด ๋ฐ์ดํฐ ์ ๋ฌ
tableView.delegate = self //UITableViewDelegate ํ๋กํ ์ฝ์ ์ฑํ ->ํ
์ด๋ธ๋ทฐ์์ ์ฌ์ฉ์๊ฐ ์คํฌ๋กค/ํฐ์น ๋ฑ์ ์ ๋ฌ ๋ฐ์ ํ๋๋ค์ ๋ทฐ์ปจํธ๋กค๋ฌ์๊ฒ ์ ๋ฌ
tableView.rowHeight = 70 //์
ํ๋ํ๋์ ๋์ด
//cell์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด ์ฌ์ฌ์ฉ ์๋ณ์๋ฅผ ํ
์ด๋ธ๋ทฐ์ ๋ฑ๋ก
tableView.register(MakeCell.self, forCellReuseIdentifier: "cellID")
//ํ
์ด๋ธ๋ทฐ ์คํ ๋ ์ด์์ ์ค์ ๋ฉ์๋ ํธ์ถ
setupTableviewConstraints()
}
//ํ
์ด๋ธ๋ทฐ ์คํ ๋ ์ด์์ ์ค์
func setupTableviewConstraints(){
view.addSubview(tableView)
tableView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
}
//UITableViewDataSource ํ๋กํ ์ฝ ๋ฉ์๋ : ํ
์ด๋ธ๋ทฐ๊ฐ ๋ทฐ์ปจํธ๋กค๋ฌํํ
๋ช ๊ฐ์ ํ์ ๊ฐ์๊ฐ ํ์ํ์ง ๋ฌผ์ด ๋ณด๋ ์ญํ
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return cartArray.count //์์ง ๊ฐ์ ๋ฐ์ ์ค์ง ์์๊ธฐ ๋๋ฌธ์ ์ผ๋จ ์ฃผ์ -> ๋ฆฌํด๊ฐ์ ํ
์ด๋ธ๋ทฐ์ ์ ๋ฌ
return 5
}
// UITableViewDataSource ํ๋กํ ์ฝ ๋ฉ์๋: register์ ๋๊ฒจ ์ฃผ์๋ cellID๋ฅผ ์ฌ์ฉํด์ ํน์ ํ์ cell์ ๋ถ๋ฌ ์ค๊ธฐ(cellForRowAt) ์ํ ์์
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// ์
์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด ํ์์ ๊บผ๋ด์ ์บ์คํ
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath) as? MakeCell else { //MakeCell์ ํ์
์บ์คํ
return UITableViewCell()
}
cell.configure() // ์
์ ๊ตฌ์ฑํ๋ ๋ฉ์๋ ํธ์ถ
cell.selectionStyle = .none // ์
์ ํ ์ ์์ ๋ณํ์ง ์๊ฒ ์ค์
return cell
}
}