Basic Table View - Code
지난 포스팅에서는 기본적은 UI 세팅을 하였다면 이번 포스팅에서는 본격적으로 코드를 작성해보는 시간을 갖도록 하겠습니다. 바로 시작하겠습니다.
1) Data
먼저 우리가 만들 예제 어플리케이션에서 만들 데이터들을 간단하게 코드로 작성해보도록 하겠습니다.
실제 배포되는 어플리케이션에서는 이처럼 데이터를 코드로 작성하지 않고 대부분 서버에서 받아오는 형태이지만 연습 예제이니만큼 이해해주시기 바랍니다.
import UIKit
class ViewController: UIViewController {
var dataList = [[String:String]]()
/*
Dictionary를 배열로 갖는 데이터 구조.
*/
var weather:[String] =
["cloud", "snowflake", "sun", "umbrella", "wind"]
/*
보다 편리하게 사용하기 위해 날씨의 종류를 날씨 아이콘 파일명과 일치시켰습니다.
*/
var area:[String] =
["서울", "뉴욕", "도쿄", "런던", "다낭", "바르셀로나", "파리", "샌프란시스코", "보라카이", "모스크바", "베를린"]
override func viewDidLoad() {
super.viewDidLoad()
for index in 0...area.count-1{
dataList.append( [ "area":area[index], "weather":weather[index % weather.count] ] )
}
/*
사용할 데이터들을 반복해서 넣는 코드
*/
}
}
- 데이터를 임의로 넣는 방법은 여러분의 취향대로 넣으셔도 상관없습니다.
2) UITableViewDelegate, UITableViewDataSource
사용할 데이터를 작성하였다면 ViewController.swift
파일에서 ViewController
클래스가 UITableViewDelegate
, UITableViewDataSource
프로토콜을 따른다고 작성합니다.
이 포스팅에서
Delegate
가 무엇인지,Protocol
이 무엇인지는 상세히 다루지 않습니다.
/*
ViewController.swift
*/
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
/*
code
*/
}
그럼 다음과 같은 에러 메시지가 발생할 것입니다.
Type ‘ViewController’ does not conform to protocol ‘UITableViewDataSource’
바로 프로토콜을 준수하지 않았기 때문입니다.
UITableViewDataSource
프로토콜은 기본적으로 반드시 구현해야하는 메소드가 두가지 있습니다.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
/*
code
*/
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
/*
code
*/
}
- 첫 번째 메소드는
Section
에 들어갈 데이터 Row들의 갯수를 반환해주는 메소드입니다.Section
이란 하나의 리스트라고 생각하시면 됩니다. 우리의 예제에서는 지역 별로 날씨를 알려주는 어플리케이션이기 때문에dataList
의 갯수만큼의 데이터 Row가 필요할 것입니다. - 두 번째 메소드는 구체적인 하나의 Row를 나타내는
Table View Cell
을 반환하는 메소드입니다. 이 메소드에서는Cell
안에 데이터들을 직접 뿌려주는 일을 수행합니다.
3) Method Implementation
위의 메소드 소개를 토대로 메소드를 구현해보도록 하겠습니다.
tableView(_: numberOfRowsInSection)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return dataList.count }
이 메소드는 위의 소개를 이해하셨다면 크게 어려운 부분은 없으실 것입니다.
tableView(_: cellForRowAt)
말 그대로 특정 인덱스
Row
의Cell
에 대한 정보를 넣어Cell
을 반환하는 메소드입니다.func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell( withIdentifier: "Cell", for: indexPath ) let currentRowOfList = dataList[indexPath.row] let currentWeatherInfo = currentRowOfList["weather"] cell.textLabel?.text = currentRowOfList["area"] cell.detailTextLabel?.text = currentWeatherInfo switch currentWeatherInfo! { case "cloud": cell.imageView?.image = UIImage(named: "cloud.png") case "sun": cell.imageView?.image = UIImage(named: "sun.png") case "snowflake": cell.imageView?.image = UIImage(named: "snowflake.png") case "umbrella": cell.imageView?.image = UIImage(named: "umbrella.png") case "wind": cell.imageView?.image = UIImage(named: "wind.png") default: print("No Match Image") } return cell }
이제 위의 코드를 하나하나 살펴보도록 하겠습니다.
indexPath
tableView(_: cellForRowAt)
메소드는Cell
을 하나씩 생성할 때마다 호출됩니다.Cell
을 만들기 위해서는 현재 만들고 있는Cell
이 몇 번째Cell
인지를 알아야합니다. 이 정보를indexPath
가 담고있습니다.dequeueReusableCell
여러분의 카카오톡에는 친구가 몇 명이나 있으신가요? 채팅방은 몇 개가 있으신가요? 지금까지 배운 내용을 토대로 한다면 친구 목록은 친구 수 만큼의
Cell
을, 채팅방 목록은 채팅방의 수 만큼의Cell
이 있을 것이라고 생각되실 것입니다.
실상은 그렇지 않습니다. 실제로
Cell
의 갯수는 화면에서 보여줄 수 있는 최대한의Cell
의 갯수만을 생성하고 하나의Cell
이 위로 완전히 넘어가거나 아래로 완전히 내려가 보이지 않게 되면 사라진Cell
을 스크롤이 내려간만큼 새로 보여줘야할Cell
을 위해 재사용합니다.
그렇기 때문에 실제 보여주는 Row 갯수의
Cell
을 만들어놓고 스크롤을 통해 화면이 넘어가면 그때 그때 이Cell
을 생성하는 메소드인tableView(_: cellForRowAt)
가 호출되어Cell
을 생성합니다.
dequeueReusableCell
메소드는 실제로 이것을 가능케 하는 메소드입니다.
Queue
에는 실제로 화면에 보이는Cell
만 들어있고 하나의Cell
이 스크롤을 통해 화면에서 사라지면Pop
하여 재사용하여Queue
에Push
해주는 것입니다.
withIdentifier
는TableView
의 데이터를 뿌려줄Cell
을 식별하는 역할을 합니다. 그리고for
은 만들어 반환하는Cell
이 몇 번째Cell
인지를 알려주는 역할을 합니다.
특히
withIdentifier
는 상당히 중요합니다.Main.storyboard
에서 왼쪽 뷰의 목록에서Cell
을 선택하여 우측Attributes Inspector
메뉴에서Identifier
에서 위의 메소드에 넣어준withIdentifier
와 일치시켜주어야 합니다.
나머지 코드
dataList
의 순서대로Cell
을 생성하여 화면에 보여줄 것이기 때문에Cell
의 인덱스가 곧dataList
의 인덱스가 됩니다. 그리고Cell
의 인덱스를 직접적으로 다루기 위해서는indexPath.row
를 통하여 접근합니다.
그리고 우리가 선택한
Cell
의Subtitle
스타일은 기본적으로textLabel
,detailTextLabel
그리고imageView
를SubView
로 갖고 있습니다.
나머지 코드들은 지역과 날씨 그리고 날씨에 따른 이미지를
Cell
에 뿌려주는 역할을 합니다.
4) Delegate, DataSource
마지막 작업은 실제
TableView
와ViewController
를 우클릭 후 드래그를 통해 연결한 후delegate
와datasource
를 지정해주는 것입니다.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{ /* data code */ @IBOutlet weak var weatherTableView: UITableView! override func viewDidLoad() { super.viewDidLoad() /* code */ weatherTableView.delegate = self weatherTableView.dataSource = self } /* method implementation */ }
마무리
이제 만들어진 프로젝트를
Run
을 하여 결과물을 살펴보면 다음과 같은 결과물을 보실 수 있습니다.
지금까지 기본적인
TableView
를 이용한 간단한 어플리케이션을 만들어보았습니다.
다음 포스팅에서는
Cell
을 기본Cell
이 아닌 직접 디자인해보는Custom Cell TableView
를 사용하는TableView
를 만들어보는 시간을 갖도록 하겠습니다. 감사합니다.