Olive Study Room
[iOS] UITableView의 생성, cell 삭제 본문
simple Test Project 작성
import UIKit
class TestViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var korean: [String] = ["가", "나", "다" ]
var english: [String] = ["A", "B", "C" ]
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return section == 0 ? korean.count : english.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 셀 재사용
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
// 셀에 무엇을 표시할 것인가?
var text: String{
return indexPath.section == 0 ? korean[indexPath.row] : english[indexPath.row]
}
cell.textLabel?.text = text
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return section == 0 ? "한글" : "영어"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
1. cell의 Identifier기입
2. ViewController에 datasourse, delegate 대입, 코드에도 참조 추가
3. protocol 준수.
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell (셀 재사용, 셀에 무엇을 표현할 것인가?)
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int (각 섹션에 몇 개의 row를 띄울 것인가)
- UITableViewCell Style 종류
- NSIndexPath란?
UIKit에서는 NSIndexPath에 두 개의 값을 지정.
- 지정된 Path의 section 번호
: var section: Int / indexPath.section 형태로 코드에서 사용
- 지정된 Path의 row 번호 (특정 section에 속한 row)
: var row: Int / indexPath.row 형태로 코드에서 사용
- 셀 재사용 방식?
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell indentifier를 사용해 dequeueReusableCell을 하는 방식
-> Table에서 사용하는 각 cell은 heap에서 할당되고, 더 이상 사용되지 않는 cell은 heap에 반환된다
Table이 새로운 cell을 위한 공간을 찾을 때, heap에 같은 identifier인 cell이 있으면 이를 재활용한다
* 자료구조 다시 공부 필요
depth가 있는 table view
// top ViewController
import UIKit
class TestViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var table: UITableView!
// var korean: [String] = ["가", "나", "다" ]
// var english: [String] = ["A", "B", "C" ]
// Dictionary로 Dept 구현
var lang: [String : [String]] = ["Korean":["가", "나", "다"], "English" : ["A", "B", "C"]]
// func numberOfSections(in tableView: UITableView) -> Int {
// return lang.keys.count
// }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lang.count
//return section == 0 ? korean.count : english.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 셀 재사용
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
// 셀에 무엇을 표시할 것인가?
// var text: String{
// return indexPath.section == 0 ? korean[indexPath.row] : english[indexPath.row]
// }
var arr: Array = Array(lang.keys)
cell.textLabel?.text = arr[indexPath.row]
return cell
}
// func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
// return section == 0 ? "한글" : "영어"
// }
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "dept" {
if let destination = segue.destination as? TableViewController{
if let selectedIndex = self.table.indexPathsForSelectedRows?.first?.row{
destination.title = Array(lang.keys)[selectedIndex]
destination.detailList = Array(lang.values)[selectedIndex]
}
}
}
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
let name = Array(lang.keys)[indexPath.row]
self.lang.removeValue(forKey: name)
tableView.deleteRows(at: [indexPath], with: .fade)
}
// else if editingStyle == .insert{
//
// }
}
}
// bottom TableViewContoller
import UIKit
class TableViewController: UITableViewController {
// force optional unwrapping하지 않으면 오류남
var detailList: [String]!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = self.editButtonItem
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return detailList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "detailCell", for: indexPath)
cell.textLabel?.text = detailList[indexPath.row]
// Configure the cell...
return cell
}
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
let name = Array(detailList)
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
}
두가지 삭제 방식
* 필수 : 셀 삭제시 필요한 코드 ( 데이터와 셀 모두 삭제)
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
let name = Array(detailList)
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
1. edit 버튼 추가
self.navigationItem.rightBarButtonItem = self.editButtonItem
TableViewController에서만 사용 가능!! (ViewController에서 사용하려면 따로 barbuttonItem 추가 후 메서드 직접 구현해야함)
2. slider
모든 경우 사용 가능. 필수 코드만 구현해도 사용할 수 있음.
-> ViewContoller에서는 슬라이더만(따로 버튼을 만들어 구현하지 않을 시), TableViewController에서는 둘 다 가능함!
Error
1. 'unable to dequeue a cell with identifier detailCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
- cell의 identifier 설정 오류.
자료 출처 : www.boostcourse.org/mo326
'Coding > iOS' 카테고리의 다른 글
[Swift] GCD? (Dispatch Queue & OperationQueue) (1) | 2021.04.06 |
---|---|
[Swift] Json 다루기 (0) | 2021.03.12 |
1일차 - 로드맵의 이해 (0) | 2021.01.02 |
공부 시작 (0) | 2021.01.02 |
CocoaPods(코코아팟) 사용법과 프로젝트 에러 (0) | 2020.09.26 |