iPhone의 연락처 앱처럼 구분을 하여 목록을 보여주고 싶을 때가 있습니다.
블로그나 유튜브를 찾아봐도 TableView의 Section 구분만 나오는게 아닌
특정 기능까지 포함해서 나오기에 복잡해서 어려움도 많았습니다.
딱! 간단하게 TableView Section 처리하는 방법을 알아보겠습니다.
Storyboard에서 UIViewController에 TableView와 TableViewCell 을 추가해줍니다.
TableViewCell의 Attributes Inspactor 로 들어가
Identifier 를 'CellList' 라고 정해주었습니다.
이제 Swift 코드로 들어가보겠습니다.
import UIKit class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! // 임의 데이터 넣기 var items: [String] = ["Apple", "Facebook", "Google", "Kakao", "Naver", "NcSoft", "Github"] override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self } } | cs |
Storyboard의 TableView를 @IBOutlet 변수로 연결해주었고
tableVIew의 delegate, dataSource 를 'self'로 지정해 주었습니다.
extension ViewController: UITableViewDelegate, UITableViewDataSource { // Section count public func numberOfSections(in tableView: UITableView) -> Int { return Array(Set(self.items.map{ $0.first! })).count } // Section의 title func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return String(Array(Set(self.items.map{ $0.first! })).sorted()[section]) } // row 의 data 대입 public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let charactor = Array(Set(self.items.map{ $0.first! })).sorted()[indexPath.section] let cell = tableView.dequeueReusableCell(withIdentifier: "CellList", for: indexPath) cell.textLabel?.text = self.items.filter{ $0.first == charactor }[indexPath.row] return cell } // Section의 Row count public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let charactor = Array(Set(self.items.map{ $0.first! })).sorted()[section] return self.items.filter{ $0.first! == charactor }.count } } | cs |
ViewController 를 확장하여 TableView 프로토콜을 준수해 함수를 정의하였습니다.
각각 설명을 하겠습니다.
1. Section의 count를 return 합니다.
public func numberOfSections(in tableView: UITableView) -> Int | cs |
return Array(Set(self.items.map{ $0.first! })).count | cs |
items 라는 array를 map{ $0.first! } 하면 $0로 각각 한개씩 담겨지게 되고
first 변수에는 첫글자만 배열로 반환합니다.
반환된 배열을 Set 으로 담으면 중복이 제거됩니다.
Set을 다시 Array로 변환한 뒤 count를 return 합니다.
이렇게 해서 중복이 제거된 앞글자의 합을 Section count로 return 하였습니다.
2. Section의 title을 생성합니다.
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? | cs |
return String(Array(Set(self.items.map{ $0.first! })).sorted()[section]) | cs |
Section count와 동일하게 한글자를 가져오고 각 section에 맞게 title이 셋팅됩니다.
3. 각 Section의 row count를 return 합니다.
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int | cs |
let charactor = Array(Set(self.items.map{ $0.first! })).sorted()[section] return self.items.filter{ $0.first! == charactor }.count | cs |
현재 Section에 해당되는 첫번째 문자열을 추출합니다.
filter{ $0.first == charactor} 배열에 들어있는 값과 추출한 문자열을 비교하여 맞는 값의 count를 return합니다.
4. 각 row에 data를 대입합니다.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell | cs |
let charactor = Array(Set(self.items.map{ $0.first! })).sorted()[indexPath.section] let cell = tableView.dequeueReusableCell(withIdentifier: "CellList", for: indexPath) cell.textLabel?.text = self.items.filter{ $0.first == charactor }[indexPath.row] return cell | cs |
현재 Section에 해당되는 첫번째 문자열을 추출합니다.
TableViewCell을 연결해줍니다.
filter{ $0.first == charactor } 배열에 들어있는 값과 추출한 문자열을 비교하여 맞는 값을 꺼낸 뒤
그안에서 indexPath.row 에 해당되는 값을 꺼내 textLabel에 넣어줍니다.
이렇게 Section 을 간단하게 분리해 보았습니다.
응용을 한다면 날짜별로 Section을 분리하는것도 쉽게 구현이 가능합니다.
'프로그래밍 > iOS' 카테고리의 다른 글
[XCode 11] iOS 13 다크모드 해제 (0) | 2019.12.09 |
---|---|
Swift 4 UIAlertController (0) | 2019.03.05 |
Swift 4 UIRefreshControl (0) | 2019.03.04 |
Swift 4 TableViewCell SwipeAction (0) | 2019.02.21 |
Swift 4 TextView PlaceHolder (0) | 2019.02.21 |