오늘은 ViewController의 종류중 하나인 TableViewController에 대해 다뤄보고자 합니다.
TalbeViewController란?
UITableViewController란 UIViewController를 상속받는 서브클래스로 table view를 관리하는데 특화된 ViewController라고 합니다.우리가 아이폰의 설정창에서 흔히 볼 수 있는 화면을 생각하시면 이해가 빠릅니다.
이렇게 한 줄 씩 나누어져? 있는 뷰를 우리가 TableViewContorller라고 부릅니다. 그렇다면 일반 ViewController와의 차이점은 무엇이고 어떻게 만들어지는지 알아봅시다.
1. Table View Controller 이용해서 만들기
그냥 라이브러리에서 Table View Controller를 이용해서 만드는 방법이 있습니다.
2. Table View와 Talble View Cell을 일반 ViewController에 드래그&드롭해서 만들기
일반 ViewController에 TableView와 Table View Cell을 드래그&드롭해서 만드는 방법이 있습니다.
만드는 방식이 다르듯 약간의 차이를 가지고있습니다.
차이점은 두가지가 있습니다. 첫 번째로 루트 뷰가 다릅니다. ViewController의 경우 루트뷰가 UIView이고 TableViewController의 경우 Table View가 루트 뷰를 담당합니다. 두 번째는 자유도 입니다. ViewController로 만든 Table View는 크기 조정이 자유롭게 가능한 반면, TableViewController의 TableView는 크기조정이 불가합니다.
그렇다면 도대체 이 TableViewController는 왜 생긴걸까요? 바로 개발자들이 가장싫어하는 반복(노가다)를 피하기 위해서 입니다.
카카오톡 친구창을 떠올려보시길 바랍니다. 친구가 몇십명에서 몇백명까지 있을텐데 이 모든 뷰(테이블 뷰에선 셀(Cell))을 하나하나 다 지정해줘야한다면 너무 힘들겠죠... 하지만 TableViewController의 기능을 활용한다면 셀 하나에 배열처럼 인덱싱을 해주기 때문에 코드를 짜거나 후에 관리하기가 훨씬 편해집니다.
관리하는 방법 즉 테이블 뷰는 두 가지 방법으로 셀을 관리하게 해줍니다. 바로 Static(정적)인 방식과 Dynamic(동적)인 방식입니다.
Static Table View
Static Table View는 아이폰의 설정창이나 회원가입 창같은 정적인(변화가 적은) 화면을 만들 때 사용되는 방식입니다. 코드없이 스토리보드의 설정으로 구성해야합니다.
먼저 Content에서 Static Cells를 설정해줍니다.
그 이후에 저는 스타일을 Inset Grouped로 설정해줬습니다. Plain, Grouped, Inset Grouped다 차이가 있으니 한 번 꼭 확인해보세요!
다음은 셀 하나씩 스타일과 액세서리를 더해줄 수 있습니다. 스타일은 셀의 오른쪽에 파란색 선 기준으로 왼쪽 Accessory는 오른쪽 '>' 화살표를 나타냈습니다 이외에도 다른 옵션들이 많으니 확인해보시길 바랍니다.
다음은 Header와 Footer의 설정입니다 셀을 누르는 게 아니라 셀 영역(Table View Section)을 누르시고 나서 설정이 가능합니다. Header는 셀 모음의 위쪽(섹션의 위쪽) Footer는 셀 모음(섹션의 아래쪽)에 문자를 작성할 수 있게 해줍니다.
다음은 밑에 셀을 하나 더 따로 만들기 위해 Table View와 Table View Cell을 추가해줍니다. 그리고 위에서 한 작업을 동일하게 진행해줍니다. 여기서 셀의 클릭이 잘 안 될 것인데 왼쪽 탭 영역에서 클릭하면 좀 더 쉽게 선택이 가능합니다. 그리고 전 밑에 셀을 하나 더 만들어주려 섹션을 복붙하고 설정을 또 해주었습니다.( + 다크모드)
✅ 결과물
Dynamic Table View
Dynamic Table View는 카카오톡 친구 프로필이나 채팅방 목록처럼 실시간으로 이벤트를 줄 수 있는 즉 동적인 화면을 만드는데 사용하는 방식입니다. 이 방법은 스토리보드가 아니라 코드를 작성해 제어합니다.
새로 TableViewController를 만들어주고 SettingTableViewController 클래스를만들어 연결해줍니다. 여기서 주의할 점은 클래스를 만들 때 UIViewController의 서브 클래스가 아니라 UITableViewController의 서브클래스로 만들어주어야합니다.
그리고 SettingTableViewController를 만들면 기본적으로 나오는 주석들과 코드들을 깔끔하게 다 지워주고 나서 코드를 작성해줍니다.(분명 저 함수들도 각자 기능을 가지고 있겠지만... 아직은 잘 모르겠습니다😂😂 후에 공부하면 한 번 다뤄보도록 하겠습니다.)
Dynamic Table View를 다루는데 있어 필수적인 코드는 두 개가 있습니다. 바로 tableView(_:numberOfRowsInSection:)메소드와 cellForRow(at:)메소드입니다.
tableView(_:numberOfRowsInSection:) 함수는 셀의 개수를 주는 함수입니다. 만약 카톡 친구 100명이 있다면 100개의 셀을 주면되고 3000개가 있다면 3000개의 셀을 주면 되는것입니다. 그리고 cellForRow(at:)함수는 셀의 디자인과 데이터(카톡 이름, 상태메세지)등을 나타냅니다. 예제 코드를 살펴봅시다.
import UIKit
class SettingTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
// 섹션의 갯수(필수 아님)
override func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
// 셀의 갯수(필수)
// ex. 카톡친구 100명 > 셀 100개, 3000명 > 셀 3000개
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 3
} else if section == 1 {
return 4
} else {
return 1
}
}
// 셀의 디자인과 데이터(필수)
// ex. 카톡이름, 프로필 사진, 상태메시지 등
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 어떤 셀을 쓸껀지 정해줘야 하기 때문에 이름을 정해준다(identifier 부여)
let cell = tableView.dequeueReusableCell(withIdentifier: "setting")!
if indexPath.section == 0 {
cell.textLabel?.text = "0번 인덱스 텍스트"
} else if indexPath.section == 1 {
cell.textLabel?.text = "1번 인덱스 텍스트"
} else if indexPath.section == 2 {
cell.textLabel?.text = "2번 인덱스 텍스트"
}
return cell
}
}
cellForRowAt: 함수를 보면 tableView.dequeueReusableCell(withIdentifier:_)로 identifier를 정해줬습니다. 어떤 셀에 적용시킬지 알려줘야하기 때문입니다. 때문에 이를 사용할 시에 밑의 그림과 같이 반드시 identifier를 setting으로 일치 시켜주어야합니다.
또한 여기서 추가적으로 section이라는 프로퍼티를 사용하였는데 section은 셀의 묶음이라고 보시면되겠습니다. 위의 예제에서 밑에 셀을 하나 더 만들어 줬을때 셀이 따로 떨어졌는데 이는 섹션이 하나 더 추가된 것이라고 보면 됩니다. 즉 섹션은 셀의 묶음인데 Dynamic Table View는 Section을 설정할 때 배열처럼 0부터 인덱스를 부여하고 마찬가지로 작은 셀에도 하나씩 인덱스를 부여해 줍니다.
그래서 결과적으로 섹션이 0인 곳의 셀 값은 "0번 인덱스 텍스트", 1은 "1번 인덱스 텍스트", 2는 "2번 인덱스 텍스트"라는 결과를 나타냅니다.
이를 활용해 화면을 만들어 보겠습니다. 코드는 다음과 같습니다.
import UIKit
class SettingTableViewController: UITableViewController {
var allSettingCell: [String] = ["공지사항", "실험실", "버전정보"]
var mySetting: [String] = ["개인/보안", "알림", "채팅", "멀티프로필"]
var etcSetting: [String] = ["고객센터/도움말"]
var headerTitle: [String] = ["전체 설정", "개인 설정", "기타"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return headerTitle[section]
} else if section == 1 {
return headerTitle[section]
} else if section == 2 {
return headerTitle[section]
} else {
return nil
}
}
// 섹션의 개수 나타내주는 함수
override func numberOfSections(in tableView: UITableView) -> Int {
return headerTitle.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return allSettingCell.count
} else if section == 1 {
return mySetting.count
} else {
return etcSetting.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "setting")!
// indexPath : 셀은 각각의 섹션내에서 인덱스값이 0,1,2 셀은 0,1,2,3으로 시작됨 >> (0,1), (2, 3)으로 이루어짐
// 때문에 indexPath.row, indexPath.section을 전달받는다. >> 인덱싱을 활용해 값 설정 가능해진다.
if indexPath.section == 0 {
cell.textLabel?.text = allSettingCell[indexPath.row]
cell.textLabel?.font = .systemFont(ofSize: 12)
} else if indexPath.section == 1 {
cell.textLabel?.text = mySetting[indexPath.row]
cell.textLabel?.font = .systemFont(ofSize: 12)
} else if indexPath.section == 2 {
cell.textLabel?.text = etcSetting[indexPath.row]
cell.textLabel?.font = .systemFont(ofSize: 12)
}
return cell // setting이라고 이름 붙여준 UITableViewCell을 리턴해줌
}
}
✅ 결과
간단하게 Table View Controller에 대해 알아보았습니다. 일반 뷰컨트롤러와 달라 조금 어려운 거 같습니다. 아직 배워야될 것들도 많이 남았다 생각하기에 후에 배우면 내용은 보충하도록 하겠습니다.
참고
https://developer.apple.com/documentation/uikit/uitableviewcontroller/
'iOS' 카테고리의 다른 글
[iOS] WKWebView (0) | 2022.07.28 |
---|---|
[iOS] 컬렉션뷰(Collection View) (0) | 2022.07.21 |
[iOS] TableViewController - Custom Table View Cell (0) | 2022.07.19 |
[iOS] 생명주기 + AppDelegate & SceneDelegate (0) | 2022.07.17 |
@IBOutlet @IBAction에 대하여 (0) | 2022.06.17 |