iOS
웹개발자의 iOS 개발기(10) - [UIKit] 테이블뷰, TableView
whh__
2025. 1. 26. 23:16
테이블뷰에 대하여 공부해 보았습니다.
UIKit은 Delegate 패턴으로 UI요소를 컨트롤하여서 해당 패턴이 익숙해질 때까지 많이 연습이 필요해 보입니다.
01. 테이블뷰로 화면 그리기
MyTableViewController.swift
테이블뷰 그려보기
- TableView 생성, 그 안에 TableViewCell 생성
- Table View Cell 식별자 정의
- 코드 작성
import UIKit
class MyTableViewController: UIViewController {
@IBOutlet weak var myTableView: UITableView!
let cellData = ["Hello TableView!", "Hello Swift!", "Hello UIKit!"]
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .brown
myTableView.backgroundColor =
.green
myTableView.delegate = self
myTableView.dataSource = self
}
}
extension MyTableViewController: UITableViewDelegate, UITableViewDataSource{
// cell 개수 return, return한 만큼 for문 돌면서 화면에 그리기 때문에 실제 개수와 다르면 에러
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
cell.textLabel?.text = cellData[indexPath.row]
return cell
}
}
02. Delegate 친해지기
Delegate
- 위임자
- 대리자
TableView의 UITableViewDelegate, UITableViewDataSource를 상속받아 함수를 구현하면
Delegate 패턴으로 개발자가 호출하는 게 아닌 TableView가 내부적으로 호출해서 사용한다.
DelegateTestController.swift
import UIKit
protocol AdminDelegate {
func doTask()
}
class DelegateTestController: UIViewController {
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var helloLabel: UILabel!
var admin: Admin?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
admin = Admin(delegate: self)
}
@IBAction func didTabButton(_ sender: Any) {
if let name = nameTextField.text {
helloLabel.text = "Hello \\(name)!"
}
admin?.delegate.doTask()
}
}
extension DelegateTestController: AdminDelegate {
func doTask() {
print("저 지금 일 잘하고 있습니다!")
}
}
struct Admin {
var delegate: AdminDelegate
}
MyTableViewController.swift
import UIKit
class MyTableViewController: UIViewController {
@IBOutlet weak var myTableView: UITableView!
let cellData = ["Hello TableView!", "Hello Swift!", "Hello UIKit!"]
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .brown
myTableView.backgroundColor =
.green
myTableView.delegate = self
myTableView.dataSource = self
}
}
extension MyTableViewController: UITableViewDelegate, UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
// cell 개수 return, return한 만큼 for문 돌면서 화면에 그리기 때문에 실제 개수와 다르면 에러
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
cell.textLabel?.text = cellData[indexPath.row]
return cell
}
}
UIKit에서는 위와 같이 Delegate 패턴이 사용되기 때문에 이 디자인 패턴에 익숙해져야겠다.
03. UItableviewDelegate 살펴보기
UITableViewDelegate, UITableViewDataSource
- 실제로 해당 protocol의 내부 함수를 직접 보는 게 도움이 된다.
- DataSource는 테이블 뷰가 이 데이터로 어떻게 그릴건지에 대한 메서드 위주
- Delegate는 액션 위주 메서드
04. TableView로 간단한 화면 그리기
TodoViewController.swift
import UIKit
struct TodoItem {
let title: String
var isCompleted: Bool
}
class TodoViewController: UIViewController {
@IBOutlet weak var todoTableView: UITableView!
var data: [TodoItem] = [
TodoItem(title: "커밋하기", isCompleted: false),
TodoItem(title: "운동하기", isCompleted: true)
]
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .gray
todoTableView.backgroundColor = .brown
todoTableView.dataSource = self
todoTableView.delegate = self
}
}
extension TodoViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = todoTableView.dequeueReusableCell(withIdentifier: "todoCell", for: indexPath)
cell.textLabel?.text = data[indexPath.row].title
if data[indexPath.row].isCompleted {
cell.textLabel?.textColor = .green
} else {
cell.textLabel?.textColor = .red
}
return cell
}
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let myAction = UIContextualAction(style: .normal, title: "완료") {
action, view, completionHandler in
self.data[indexPath.row].isCompleted.toggle()
self.todoTableView.reloadData()
completionHandler(true)
}
return UISwipeActionsConfiguration(actions: [myAction])
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
todoTableView.deselectRow(at: indexPath, animated: true)
}
}