TabelView를 적용하기전
공부를 하면 좋겠다고 생각해서 정리하게 되었습니다
UITableView
단일 열에 행을 사용하여 데이터를 표시하는 뷰
그림으로 말하자면
아래처럼 이렇게 한 줄로 표현한다라고 생각하면 됩니다
_
_
_
_
Overview
iOS의 테이블 뷰는 vertical 스타일로 스크롤되는 행의 컨텐츠를 표시하고 있습니다
테이블의 각 행은 앱의 한가지 컨텐츠를 포함하고 있습니다
연락처 앱
각 연락처 이름을 별도의 행에 표시
설정 화면
사용할 수 있는 설정 그룹을 표시하고 있습니다
테이블 뷰를 구성하여 긴 목록의 행을 표시할 수 있고 관련된 섹션으로 나눠서 행을 그룹으로 만들어 표시하여
육안으로 더 잘 보이게 만들 수 있습니다
테이블은 데이터가 아주 구조화되거나 계층적으로 구조화된 앱에서 사용하고 있습니다
계층적으로 데이터화된 앱들은 네비게이션 뷰 컨트롤러와 함께 테이블을 사용해서 다양한 탐색에 용이합니다
예를 들어서 설정(Settings)앱은 시스템 설정을 구성하기 위해 테이블과 네비게이션 컨트롤러를 사용합니다
UITableView는 테이블의 기본적인 인터페이스(외관 이미지) 관리하지만 실제 컨텐츠를 표시하는 셀은 UITableViewCell
을 애플에서 제공하고 있습니다
셀 구성은 텍스트와 이미지를 간단히 조합해서 표시하지만 원하는 모든 오브젝트(컨텐츠)를 표시할 수 있는 커스텀 셀도 만들 수 있습니다
또한 셀 그룹에 대해서 추가하고 싶은 오브젝트나 정보가 있으면
header / footer views(상단 뷰 / 하단뷰)로 적용할 수 있습니다
Header View
테이블 뷰의 각 섹션 또는 테이블 뷰 전체의 상단에 추가할 수 있는 뷰를 의미하고 있습니다
이 뷰는 셀의 그룹에 대한 제목이나 설명을 제공하거나 특정 작업을 위한 버튼이나 검색 바와 같은 인터페이스 요소를 배치하는 다양한 목적으로 사용될 수 있습니다
Footer View
전체 테이블 뷰 끝에 footer view를 제공하는 메서드를 추가하고 이를 통해서 각 섹션에 대한 설명이나 요약 정보를 제공할 수 있습니다
간단한 예시
import UIKit
class MyTableViewController: UITableViewController {
let sections = ["Section 1", "Section 2", "Section 3"]
let items = [["Item 1", "Item 2"], ["Item 3", "Item 4"], ["Item 5", "Item 6"]]
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = items[indexPath.section][indexPath.row]
return cell
}
// 섹션별 헤더 제목 설정
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
// 섹션별 푸터 제목 설정
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return "Footer for \(sections[section])"
}
}
커스텀 뷰 사용해서 헤더와 푸터 사용
import UIKit
class MyTableViewController: UITableViewController {
let sections = ["Section 1", "Section 2", "Section 3"]
let items = [["Item 1", "Item 2"], ["Item 3", "Item 4"], ["Item 5", "Item 6"]]
//⭐️numberOfSections(in:): 테이블 뷰에 표시할 섹션의 갯수반환
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
//⭐️각 섹션별로 표시할 행의 개수를 반환
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items[section].count
}
//⭐️특정 IndexPath에 해당하는 셀을 반환하고 설정
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = items[indexPath.section][indexPath.row]
return cell
}
// 커스텀 섹션 헤더 뷰 설정
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = .lightGray
let label = UILabel()
label.text = sections[section]
label.frame = CGRect(x: 16, y: 5, width: tableView.frame.width, height: 20)
headerView.addSubview(label)
return headerView
}
// 커스텀 섹션 푸터 뷰 설정
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView()
footerView.backgroundColor = .lightGray
let label = UILabel()
label.text = "Footer for \(sections[section])"
label.frame = CGRect(x: 16, y: 5, width: tableView.frame.width, height: 20)
footerView.addSubview(label)
return footerView
}
// 헤더 뷰의 높이 설정
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 30
}
// 푸터 뷰의 높이 설정
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 30
}
}
Save and restore the table's current state
테이블 뷰는 UIKit 앱에서 restoration을 제공하고 있습니다 테이블의 데이터를 저장하고 복원하려면 비어있지않고 값이 있는 테이블 뷰에서 restorationIdentifier 프로퍼티를 할당하면 됩니다.
부모 뷰 컨트롤러를 저장할때 테이블뷰는 자동적으로 현재 선택된 행과 표시된 행의 인덱스 경로를 자동으로 저장됩니다
테이블 데이터 소스 자체가 UIDataSourceModelAssociation 프로토콜을 채택하고 있다면 테이블은 인텍스 경로 대신 제공된 고유 ID를 저장하게 됩니다
TableView 생성
frame의 경우 코드로 작성한 경우 지정생성자를 호출하게되고
init?같은 경우는 스토리보드나 인터페이스 빌더에서 설정한 테이블 뷰 객체를 로드하고 초기화하기 위해서 입니다
Providing the data and cells
dataSource 속성은 테이블 뷰의 데이터와 관련된 작업을 수행합니다
이 프로퍼티는 UITableViewDataSource 프로토콜을 채택하고 있고 테이블 뷰의 데이터를 관리하고
테이블 셀을 생성하고 구성하는 역할을 하고있습니다
dataSource를 사용하게되면 테이블 뷰에서 다양한 데이터를 표시할 수 있고 상호작용으로 관리가 가능합니다
테이블 뷰는 데이터가 보여지는 것만 관리하고 데이터자체는 관리하고 있지 않습니다
그래서 데이터를 관리하려면 이 프로토콜을 채택하여 테이블에 제공해야합니다
이 객체는 테이블의 데이터와 상호작용이 가능합니다 그리고 테이블의 데이터를 직접적으로 관리하거나
앱의 다른 부분을 통해서도 데이터 관리가 가능합니다
테이블 뷰에 표시할 행의 갯수를 알 수 있습니다
테이블 뷰에 표시되는 행에 대한 셀을 제공합니다
테이블 뷰의 header / footer 제공합니다
테이블 인덱스로도 반환이 가능합니다
기본 데이터를 변경해야할때 업데이트도 가능합니다
//테이블 행 개수를 반환하고 있습니다
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0 //테이블에 표시할 행이 없기 때문에 0입니다
}
//각 행마다 셀 객체를 제공하고 있습니다
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 적절한 타입의 셀을 가져오고 있습니다
let cell = tableView.dequeueReusableCell(withIdentifier: "cellTypeIdentifier", for: indexPath)
// 셀 컨텐츠 저장
cell.textLabel!.text = "Cell text"
return cell
}
그리고 row 테이블 뷰 객체는 sectin 속성을 사용하여 셀의 위치를 알려줍니다
보통 인텍스는 0부터 시작하기 때문에 아래 그림처럼 순서를 알 수 있는 고유 식별 값이 있습니다
테이블 행의 내용을 관리하는 뷰 입니다
셀은 주로 앱의 사용자 지정 내용을 구성하고 표시하는데 사용합니다
UIViewTableViewCell
셀의 선택 영역 / 색상 적용
세부 정보 또는 공개 제어와 같은 표준 액세서리 뷰 추가
셀을 편집 가능한 상태 만들기
표에 시각적 계층 구조를 만들기 위해서 셀의 내용을 들여쓰기
table view 데이터를 채워넣기에 앞서 테이블뷰는 한가지의 집합체로 만들 수도 있지만 다양한 그룹을 만들 수도 있습니다
그리고 그룹으로 나눈다음 데이터를 넣을때 데이터 소스 객체를 사용해서 테이블의 셀을 동적으로 만들고 스토리보드에서
정적으로 제공하고 있습니다
이렇게 테이블 뷰를 나눌려면 데이터 기준이 필요합니다
그래서 여기서 테이블 뷰에서 각각 인덱스 번호를 부여하는 방법입니다
func numberOfSections(in tableView: UITableView) -> Int // Optional
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
이러한 방법으로 구현할 때 행 및 섹션 수를 가능한 빨리 반환할 수 있습니다
섹션 정보를 쉽게 검색할 수 있는 데이터 방식으로 데이터를 구조화 할 수 있습니다
배열을 사용해서 테이블을 관리하거나 딕셔너리로 사용해서 카테고리별로 저장하는 방법도 고려해볼 수 있습니다
var hierarchicalData = [[String]]()
override func numberOfSections(in tableView: UITableView) -> Int {
return hierarchicalData.count
}
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return hierarchicalData[section].count
}
그리고 정적 데이터가 있는 테이블 뷰는 해당 데이터를 관리하는 개체가 필요하다고 합니다
그리고 다른 컨텐츠가 거의 없거나 전혀 없는 경우에 사용할 수 있는 UITableViewController도 볼 수 있습니다
https://developer.apple.com/documentation/uikit/uitableviewcontroller
그리고 UITableViewDelegate가 가능하여
여러가지 기능을 대리로 업데이트가 가능합니다
UITableViewDataSource / UITableViewDelegate 정리
UITableViewDataSource
DataSource: TableView를 생성하고 수정하는 데 필요한 정보를 TableView 객체에 제공합니다.
- numberOfSections: 총 섹션 개수를 묻는 메서드 (선택적)
- numberOfRowsInSection: 각 섹션에 표시할 행의 개수를 묻는 메서드 (필수)
- cellForRowAt: 특정 인덱스 Row의 Cell에 대한 정보를 넣어 Cell을 반환하는 메서드 (필수)
- titleForHeaderInSection: 특정 섹션의 헤더 타이틀을 묻는 메서드 (선택적)
- titleForFooterInSection: 특정 섹션의 푸터 타이틀을 묻는 메서드 (선택적)
- canEditRowAt: 특정 위치의 행이 편집 가능한지 묻는 메서드 (선택적)
- canMoveRowAt: 특정 위치의 행을 재정렬할 수 있는지 묻는 메서드 (선택적)
- sectionIndexTitles: Table view 섹션 인덱스 타이틀을 묻는 메서드 (선택적)
- sectionForSectionIndexTitle: 인덱스에 해당하는 섹션을 알려주는 메서드 (선택적)
- commit forRowAt: 스와이프 모드, 편집 모드에서 버튼을 선택하면 호출되는 메서드 (선택적)
- moveRowAt: 행이 다른 위치로 이동되면 어디에서 어디로 이동했는지 알려주는 메서드 (선택적)
UITableViewDelegate
Delegate: TableView의 시각적인 부분을 설정하고, 행의 액션 관리, 액세서리 뷰 지원 및 테이블 뷰의 개별 행 편집을 도와줍니다.
- didSelectRowAt: 행이 선택되었을 때 호출되는 메서드
- didDeselectRowAt: 행이 선택 해제되었을 때 호출되는 메서드
- heightForRowAt: 특정 위치 행의 높이를 묻는 메서드
- viewForHeaderInSection: 지정된 섹션의 헤더 뷰에 표시할 View가 어떤 건지 묻는 메서드
- viewForFooterInSection: 푸터뷰에 표시할 View가 어떤 건지 묻는 메서드
- heightForHeaderInSection: 지정된 섹션의 헤더 뷰의 높이를 묻는 메서드
- heightForFooterInSection: 푸터뷰의 높이를 묻는 메서드
- willBeginEditingRowAt: 테이블 뷰가 편집 모드에 들어갔을 때 호출되는 메서드
- didEndEditingRowAt: 테이블 뷰가 편집 모드에서 나왔을 때 호출되는 메서드
- willDisplay: 테이블 뷰가 셀을 사용하여 행을 그리기 직전에 호출되는 메서드
- didEndDisplaying: 테이블 뷰로부터 셀이 화면에 사라지면 호출되는 메서드
요약
- DataSource는 TableView에 데이터를 제공하고, 테이블의 구조를 설정합니다.
- Delegate는 TableView의 시각적인 부분을 관리하고, 사용자 상호작용 및 행의 모습을 조정합니다.
- 각 메서드들은 TableView의 동작을 세밀하게 커스터마이징할 수 있는 다양한 기능을 제공합니다.
- DataSource와 Delegate는 TableView의 필수적인 부분을 담당하며, 적절히 구현하여 원하는 TableView를 구현할 수 있습니다.
dequeueResusableCell
컬렉션뷰나 테이블뷰는 재사용 가능한 셀을 만들어줍니다
보통 큐에 넣어서 관리하게 됩니다
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 재사용 가능한 셀을 가져오거나 새로운 셀을 만듭니다.
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath)
// 셀을 구성합니다.
cell.textLabel?.text = "Row \(indexPath.row)"
cell.detailTextLabel?.text = "Section \(indexPath.section)"
return cell
}
https://developer.apple.com/documentation/uikit/uitableview
https://developer.apple.com/documentation/uikit/uitableviewcell
https://developer.apple.com/documentation/uikit/uitableviewdatasource
https://developer.apple.com/documentation/uikit/uitableview/1614955-datasource
https://developer.apple.com/documentation/uikit/uitableview/style
추후 만약에 내가 클릭되는 테이블 뷰를 만들게 된다면 이 티스토리를 한 번 참조해도 좋을것 같다
'UIKit' 카테고리의 다른 글
iOS | GCD에 관하여 - 1 (0) | 2024.07.15 |
---|---|
UIKit | ViewController 생명 주기 (0) | 2024.07.12 |
UIKit | UIView 어떤식으로 동작되고 있는가? (0) | 2024.07.02 |
UIKit | 스토리보드 없이 코드로만 구현하고 싶다면? -1 (2) | 2024.07.01 |
UIKit | 모서리 둥글게 만들기 (0) | 2024.06.11 |