목표
- 테이블뷰에 dynamic 데이터를 제공하는 방법
- 테이블뷰에서 사용자 액션에 반응하는 방법
- 미리 정의된 UITableViewCell 스타일 사용하여 테이블뷰 구성하는 방법
- 테이블뷰 데이터 refresh 하는 방법
용어
- accessory view
테이블뷰 셀이 가지고 있는 부가적인 정보 제공을 위한 뷰 - index path
테이블뷰에서 cell의 section과 row를 identify하기 위해 사용됨
nested array collection 트리의 특정 node를 향한 path를 나타냄 - table view
여러 아이템들을 리스트로 표시하기 위한 UI - dequeue
cell을 재사용하기 위한 선택과 준비 프로세스를 일컫는 말
테이블뷰가 특별한 caching 시스템을 사용하는데, 그건 바로 표시했던 cell을 다시 사용하는 것. - readability margin
오토레이아웃이 여러 종류의 기기에서 가독성 있는 마진을 설정할 수 있게 한다 - table view cell
테이블뷰셀은 눈에 보이는 rows를 구성하는 오브젝트들을 참조하며, rows가 눈에 보이는 동안에는 그 오브젝트들을 캐시*한다.
*캐시: 주 메모리에 있는 것을 일시적으로 보관 - dynamic
변화하는 데이터를 말함, static 데이터의 반대말. - reorder control
테이블뷰에서 사용자가 셀을 옮길 수 있도록 함 - zero-based
index가 0부터 시작하는 것을 말함
테이블뷰의 상속 관계
UIView > UIScrollView > UITableView
테이블뷰를 추가하는 방안 2가지
MVC 패턴을 상기하면서 보자. 아래에서 말하는 테이블뷰는 View이고, 테이블뷰 컨트롤러는 Controller이다.
- 테이블뷰 인스턴스를 뷰컨트롤러(범용)의 뷰에 추가한다.
자유도가 높다. 테이블뷰의 위치, 사이즈를 자유롭게 설정할 수 있다. 복잡한 뷰에 테이블뷰가 포함된 화면을 만들어야할 때 권장. - 테이블뷰 컨트롤러를 스토리보드에 추가한다. 테이블뷰 컨트롤러는 하나의 테이블뷰 인스턴스를 관리한다.
편하다. 가령 키보드가 화면에 올라왔을 때 처리해야할 이슈들을 테이블뷰 컨트롤러가 알아서 해결해준다. 테이블뷰 컨트롤러 자신이 data source 이자 delegate 처럼 동작한다. 테이블뷰 위 아래로 header view, footer view를 추가해서 다른 뷰를 붙일수도 있다.
테이블뷰 스타일
Index paths
특정 section 안에 특정 row를 가리킴
indexPath.row
indexPath.section
Cell dequeueing
테이블뷰에 표시할 형식에 따라 여러가지 cell 타입을 만들 수 있음. "prototype cell"
cell 타입마다 reuseIdentifier를 string으로 지정해줄 수 있음.
storyboard > table view cell 선택 > Attributes inspector > Reuse Identifier 옵션
재사용 큐 (큐: 줄지어서 기다리고 있는 것) "stockpile"
cell이 화면 밖으로 나가면 해당 cell은 재사용 큐에 들어가게 된다.
테이블뷰 인스턴스 메소드인 dequeueReusableCell(withIdentifier:for:)를 사용하여,
재사용 큐 중에 사용할 수 있는 (identifier이름의) 셀이 있는지 확인 하고 있다면 indexPath로 가져오라
Table View Protocols
역시 MVC 패턴을 유념해서 보자.
data source
dynamic table view 오브젝트는 반드시 data source 오브젝트를 갖고있다. 이 data source가 테이블 뷰(View)와 앱의 데이터 모델(Model)사이의 중간 역할(Controller)을 한다.
테이블뷰 자신이 얼마나 row를 표시할지 cell을 어떻게 표시할지 필요한 것만 요청을 하면 더 적은 리소스가 들기 때문
UITableViewDataSource 라는 이름의 프로토콜을 받아들임
필요한 데이터를 제공할 책임을 갖는다. 표시할 rows가 몇 개 인지, 각 row에 무엇이 들어가는지.
Table view data source를 구성하는 3개의 함수
- numberOfSections
섹션의 개수를 받아오는 함수. 적지 않으면 1개로 간주하지만 명시적으로 적는 습관이 좋다. - numberOfRowsInSection
섹션에 나타날 row의 개수를 받아오는 함수
테이블뷰 섹션의 수만큼 호출된다. 각 섹션마다 row가 몇개인지 내야하므로. - cellForRowAt
- cell을 dequeueing 해서 가져온다
let cell = tableView.dequeueReusableCell(withIdentifier: "EmojiCell", for: indexPath)
- 표시할 model 오브젝트를 가져온다.
index path가 section과 row 두가지 프로퍼티를 갖고있다는 것을 기억하자.
let emoji = emojis[indexPath.row]
- cell 프로퍼티에 model 프로퍼티를 채운다
cell.textLabel?.text = "\(emoji.symbol) - \(emoji.name)" cell.detailTextLabel?.text = emoji.description
- 채워진 cell을 리턴한다. (이 cell을 테이블뷰에 넣어줘)
return cell
- cell을 dequeueing 해서 가져온다
Table view delegate
테이블뷰 API의 두번째 프로토콜은 delegate이다. 이 오브젝트는 UITableViewDelegate 프로토콜을 따른다. 외형과 동작에 관한 역할.
Edit button
테이블뷰 Edit 버튼 설정하기 두가지 방법
- 스토리보드에서 bar button item을 navigation bar에 추가한 후, @IBAction으로 연결, 테이블뷰의 편집모드를 설정하는 코드 작성
@IBAction func editButtonTapped(_ sender: UIBarButtonItem) { let tableViewEditingMode = tableView.isEditing tableView.setEditing(!tableViewEditingMode, animated: true) }
- viewDidLoad()에서 코드 작성
미리 작성돼 있고 uncomment 처리만 하면 됨. 심지어 edit / done 글자가 토글되는 것까지 반영돼있음
override func viewDidLoad() { super.viewDidLoad() navigationItem.leftBarButtonItem = editButtonItem }
Reorder cells
테이블뷰가 셀의 순서를 매니징 할 수 있는 기능을 제공한다. UITableViewCell 클래스는 showReorderControl 프로퍼티를 제공한다.
true 값일 경우 테이블뷰는 편집모드가 되고 tableView(_:moveRowAt:to:) 라는 data source 메소드가 implement된다.
이 메소드가 호출되면, fromIndexPath.row의 데이터가 remove되고 그 값이 to.row로 이동한다.
삭제 기능 없애기
Reload Data
다른 뷰 컨트롤러에서 새 모델 오브젝트를 추가한다고 가정할 때, 테이블뷰는 이미 데이터가 로드된 상태이므로 사용자가 추가한 새 데이터는 반영되지 않았을 것이다.
테이블뷰가 자체적으로 가지고 있는 인스턴스 메소드로 reloadData()를 사용하여 테이블뷰를 refresh할 수 있다. 다른 뷰 컨트롤러에서 새로 데이터를 추가한 경우라면, 테이블뷰 컨트롤러의 viewWillArear 메소드에서 이를 실행하면 된다.
'[도서] App development with Swift' 카테고리의 다른 글
Unit 4 - Lesson 8: System View Controllers (0) | 2021.11.06 |
---|---|
Unit 1 - Lesson 4: Control Flow (0) | 2021.10.22 |
Unit 1 - Lesson 3: Operators (0) | 2021.10.21 |
Unit 1 - Lesson 2: Constants, Variables, and Data Types (0) | 2021.10.21 |
Unit 1 - Lesson 1: Introduction to Swift and Playgrounds (0) | 2021.10.21 |