Search
Duplicate

Cell을 재사용시 생기는 문제점과 해결방안

생성일
2023/08/09 11:59
태그
Swift

Cell을 재사용시 생기는 문제점과 해결방안

보통 테이블 뷰와 컬렉션 뷰를 설계할 때는 그냥 셀을 사용하지 않고, 메모리 관리 측면에서 효율적인 재활용 셀 (dequeueReusableCell)을 사용한다.
하지만 셀을 재활용하다 보니 생기는 문제점이 몇 가지가 있다. 대표적인 문제점이 바로 셀의 UI나 속성들이 중첩되거나 반복되는 경우이다.

해결방안

Cell 코드에
var isTouched: Bool? { didSet { if isTouched == true { heartButton.setImage(UIImage(systemName: "heart.fill"), for: .normal) heartButton.tintColor = UIColor.red } else { heartButton.setImage(UIImage(systemName: "heart"), for: .normal) heartButton.tintColor = UIColor.lightGray } guard let indexPath = getCurrentIndexPath() else { return } delegate?.didTapHeartButton(at: indexPath) } }
Swift
복사
ViewController 코드에
if favKinders.contains(where: { $0.kinderName == kinder.kinderName }) { cell.isTouched = true } else { cell.isTouched = false }
Swift
복사
이렇게 하면 해결이 된다.

전체코드

ListViewController.swift
extension ListViewController: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return kinders.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "KinderCell", for: indexPath) as! ListTableViewCell let kinder = kinders[indexPath.row] cell.kinderNameLabel.text = kinder.kinderName cell.kinderAddressLabel.text = kinder.kinderAddress let insideAirColor = calculateInsideAir(for: kinder.insideAir) let disinfectionColor = calculateDisinfection(for: kinder.disinfection) let illuminanceColor = calculateIlluminance(for: kinder.illuminanceDate) let dustColor = calculateDust(for: kinder.dustDate) cell.insideAirImageVIew.backgroundColor = insideAirColor cell.deinfectionImageView.backgroundColor = disinfectionColor cell.illuminanceImageView.backgroundColor = illuminanceColor cell.dustImageView.backgroundColor = dustColor cell.delegate = self if favKinders.contains(where: { $0.kinderName == kinder.kinderName }) { cell.isTouched = true } else { cell.isTouched = false } return cell } }
Swift
복사
ListTableViewCell
// // ListTableViewCell.swift // OurKids // // Created by KIM Hyung Jun on 2023/08/14. // import UIKit protocol ListTableViewCellDelegate: AnyObject { func didTapHeartButton(at indexPath: IndexPath) } class ListTableViewCell: UITableViewCell { @IBOutlet weak var backView: UIView! @IBOutlet weak var kinderNameLabel: UILabel! @IBOutlet weak var kinderAddressLabel: UILabel! @IBOutlet weak var heartButton: UIButton! @IBOutlet weak var insideAirImageVIew: UIImageView! @IBOutlet weak var dustImageView: UIImageView! @IBOutlet weak var deinfectionImageView: UIImageView! @IBOutlet weak var illuminanceImageView: UIImageView! weak var delegate: ListTableViewCellDelegate? var isTouched: Bool? { didSet { if isTouched == true { heartButton.setImage(UIImage(systemName: "heart.fill"), for: .normal) heartButton.tintColor = UIColor.red } else { heartButton.setImage(UIImage(systemName: "heart"), for: .normal) heartButton.tintColor = UIColor.lightGray } guard let indexPath = getCurrentIndexPath() else { return } delegate?.didTapHeartButton(at: indexPath) } } override func awakeFromNib() { super.awakeFromNib() configureUI() } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } func configureUI() { insideAirImageVIew.layer.cornerRadius = 7 insideAirImageVIew.clipsToBounds = true dustImageView.layer.cornerRadius = 7 dustImageView.clipsToBounds = true deinfectionImageView.layer.cornerRadius = 7 deinfectionImageView.clipsToBounds = true illuminanceImageView.layer.cornerRadius = 7 illuminanceImageView.clipsToBounds = true } @IBAction func heartButtonTapped(_ sender: UIButton) { if heartButton.imageView?.image == UIImage(systemName: "heart") { heartButton.setImage(UIImage(systemName: "heart.fill"), for: .normal) heartButton.tintColor = UIColor.red } else { heartButton.setImage(UIImage(systemName: "heart"), for: .normal) heartButton.tintColor = UIColor.lightGray } guard let indexPath = getCurrentIndexPath() else { return } delegate?.didTapHeartButton(at: indexPath) } private func getCurrentIndexPath() -> IndexPath? { guard let superView = self.superview as? UITableView else { return nil } return superView.indexPath(for: self) } }
Swift
복사

다른 해결방법