dequeueReusableCell
은 아래의 그림과 같은 과정으로 진행이된다!이런 문제를 해결하기 위해서는, cell이 reuse되기 전에 prepareForReuse()을 통하여 매번 cell을 초기화해주면 된다.
// viewcontroller.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// as ? ! 무엇으로 다운 캐스팅을 해주느냐에 따라서 cell.label?인 지 cell.label인 지 선택할 수 있다.
let cell = tableView.dequeueReusableCell(withIdentifier: "ReuseCell", for: indexPath) as! ReuseCell
cell.label.text = "\(indexPath.section), \(indexPath.row)"
if indexPath.row == 0 {
cell.backgroundColor = UIColor.systemRed
}
if indexPath.row == 1 {
cell.label2.text = "Detail"
}
// indexPath => (Section,Row)
return cell
}
// ReuseCell.swift
class ReuseCell: UITableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var label2: UILabel!
}
그런데, 위의 코드는 심각한 오류를 발생시킨다. dequeueReusableCell
과정에서 row가 0인 것 뿐만아니라, row가 1,2인 것도 다 빨간색의 background를 가지게된다.
이는 row가 0이여서 빨간색의 background를 가지게된 cell을 재사용하게되면서 생기는 문제인데, 위의 문제는 아래와 같은 코드로 해결할 수 있다.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// as ? ! 무엇으로 다운 캐스팅을 해주느냐에 따라서 cell.label?인 지 cell.label인 지 선택할 수 있다.
let cell = tableView.dequeueReusableCell(withIdentifier: "ReuseCell", for: indexPath) as! ReuseCell
cell.label.text = "\(indexPath.section), \(indexPath.row)"
if indexPath.row == 0 {
cell.backgroundColor = UIColor.systemRed
} else {
cell.backgroundColor = .none
}
if indexPath.row == 1 {
cell.label2.text = "Detail"
}
// // indexPath => (Section,Row)
return cell
}
그리고, prepareForReuse()
를 통해서도 해결이 가능하다.
prepareForReuse()
는 cell이 dequeue되기전에 실행이되며, 셀을 다 초기화해주는 코드가 들어가게 된다.
예제 코드를 통해서 활용을 알아보면, 아래와 같다.
class ReuseCell: UITableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var label2: UILabel!
// 이건 처음 로드될 때는 상관 x 다시 reuse될 cell이 생성될 때만!
override func prepareForReuse() {
super.prepareForReuse()
backgroundColor = .none
label2.text = nil
}
}