지난 시간에 봤던 UITableViewDelegate와 UITableViewDataSource를 직접 사용해 UITableView로 아주 간단한 목록 화면을 만들어보자.
우선 테이블 뷰를 사용하기 위해 UITableView를 ViewController에 하나 넣고, Constraints를 잡아주었다.
그리고 테이블 뷰의 인스펙터 가장 마지막 탭에 있는 dataSource와 delegate를 viewController에 연결해준다. (ViewController의 코드 내부에서 해줘도 되지만 그냥 이렇게 UITableView 넣었을 때 바로 연결해주는 게 마음이 편하다)
이렇게 연결해준 뒤에는 ViewController 클래스에서 UITableViewDataSource와 UITableViewDelegate 프로토콜을 채택하여 필요한 부분들을 구현해주어야 한다.
referencing outlet까지 연결하고 난 다음에 빌드를 한 번 돌려본다. 물론 에러가 날 것이다. 왜냐하면 UITableView를 사용하기 위해서는 꼭 구현해주어야 하는 메서드들이 있기 때문이다. 돌리자마자 다음과 같은 에러가 난다.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewTest.ViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x133905770'
이전 포스팅에서 알아봤듯 UITableViewDataSource에서는 두 가지 메서드가 required로 지정되어있어서 무조건 구현을 해주어야 한다.
section은 하나로, indexPath에 필요한 cell은 UITableViewCell을 생성해서 return 하도록 구현했다. (아직 cell을 추가하지 않았으므로) 그러면 실행은 된다.
아무것도 없이 줄만 그어져 있다. 왜냐, 우리는 tableView에 노출해야 할 data도 없고, 어떤 방식으로 노출할 건지를 결정하는 UITableViewCell도 그냥 기본으로 넣어 주었기 때문이다. 이제 필요한 작업들을 마무리해서 진짜 tableView에 원하는 데이터를 넣어보자.
1. cell 만들기
UITableView에서 기본적으로 사용할 수 있는 cell들이 있다. UITableViewCell을 스토리보드에 추가해두었던 tableView에 넣는다. 이름 표기를 위해 Label을 따로 추가하지 않고 UITableViewCell에서 접근 가능한 textLabel에 이름을 지정했다.
이름을 노출하는 cell이기 때문에 NameCell이라고 명명하고 Identifier도 "NameCell"로 지정해주었다. 그리고 난 다음에 cellForRowAt 메서드 내부에서 dequeueReusableCell로 사용할 cell identifier로 내가 지정한 NameCell을 가져온 뒤에 textLabel에 이름을 적어 넣었다.
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "NameCell", for: indexPath)
cell.textLabel?.text = "최록"
return cell
}
}
dequeueReusableCell은 cell을 모든 데이터를 노출할 때마다 계속 찍어내면 노출해야 하는 데이터가 적을 땐 상관없을지 몰라도 데이터가 많아지면 메모리 상으로도 아주 부담이 크기 때문에 화면에 보여질 만큼의 cell만 생성한 뒤에 그 cell들을 계속 재활용하도록 해준다. 화면 밖으로 벗어난 cell은 다시 초기화되어 다음에 보여주어야 할 데이터를 담아서 보여주게 된다.
실행 결과는 아래와 같다.
드디어 이름을 표시하는 cell이 하나 나타났다! cellForRowAt에서 직접 데이터를 넣어주었기 때문에 한 줄의 cell이 표기되었다. 만약 여러 사람을 목록에 노출시켜야 한다면 어떻게 해야할까? 우선 여러 이름을 담은 데이터를 배열로 viewController에 저장해보자.
그리고 numberOfRowsinSection과 cellForRowAt 메서드를 다음과 같이 수정한다.
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.contactsList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "NameCell", for: indexPath)
cell.textLabel?.text = self.contactsList[indexPath.row]
return cell
}
}
contactsList에 있는 사람 수 만큼 row가 만들어져야 하고, 각 row에 맞는 사람의 이름을 뽑아오도록 수정했다. 실행하면,
내가 보여주고 싶은 사람 목록을 잘 보여주는 것을 확인할 수 있다. 만약 줄이 거슬린다면 스토리보드에서 tableView의 Attributes inspector에서 separator를 none으로 설정해주면 오른쪽처럼 줄이 사라지는 것을 볼 수 있다.
만약 목록 데이터 아래는 줄이 있고, 다른 곳은 없어야 한다면....? 그땐 어쩔 수 없다. custom 하게 cell을 만들어서 사용해야 한다..ㅎ 다음 포스팅에서는 custom cell을 xib파일로 만들어서 tableView에서 사용해볼 수 있도록 변경해 봐야겠다.
'iOS' 카테고리의 다른 글
UILabel 원하는 범위만 색 변경하기 - NSMutableAttributedString 사용하기 (0) | 2022.01.16 |
---|---|
[iOS] UITableView 예제 코드 만들기 2 - Custom UITableViewCell xib 파일로 만들기 (0) | 2021.10.13 |
[iOS] UITableView 알아보기 (2) - UITableViewDelegate, UITableViewDataSource (0) | 2021.10.07 |
Apple Developer Documentation에서 API Changes 확인하기 (0) | 2021.10.07 |
[iOS] UITableView 알아보기 (1) - UITableView, UITableViewCell이 뭐야? (0) | 2021.10.05 |