-
[iOS] TableView 재사용큐iOS 2022. 10. 29. 21:18
일반적으로 테이블뷰에서 셀을 리턴하는 함수에서 셀을 재사용하도록 습관적으로 아래와 같이 코드를 작성하고 있다.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "KakaoTalkTableTableViewCell", for: indexPath) as? KakaoTalkTableTableViewCell else {return UITableViewCell() } return cell // 테이블뷰에 넣을 셀 }
dequeueReusableCell(withIdentifier:for:) 메소드는 아래와 같이 공식문서에 정의되어있다.
지정된 재사용 식별자(indexPath)에 대해 재사용이 가능한 테이블 뷰 셀 객체를 반환하고 테이블뷰에 추가한다.
이 메소드는 아래 3가지 방법으로 셀을 리턴한다.
- 기존 셀 타입
- 직접 만든 ITableViewCell 클래스
- 스토리 보드를 사용하여 만든 새로운 셀
이와 같이 dequeueReusableCell(withIdentifier:for:) 메서드만을 호출하면 셀의 재사용에 문제가 생긴다.
예를 들면, 첫번째 row의 셀의 배경색을 바꿔야한다고 가정해보자.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "KakaoTalkTableTableViewCell", for: indexPath) as? KakaoTalkTableTableViewCell else {return UITableViewCell() } // 몇번째 셀에 어떤것이 들어가는지 모르기때문에 indexPath활용 cell.profileImageView.image = chattingRoomData[indexPath.row].profileImage cell.nameLabel.text=chattingRoomData[indexPath.row].name cell.lastMessageLabel.text=chattingRoomData[indexPath.row].lastMessage // memberCountLabel은 개인톡일때 없으므로 nil값이 넘어오기 때문에 옵셔널 바인딩으로 처리 if let memberCount = chattingRoomData[indexPath.row].memberCount{ cell.memberCountLabel.text=memberCount } else { cell.memberCountLabel.isHidden=true } cell.timeLabel.text=chattingRoomData[indexPath.row].time cell.messageCountLabel.text=chattingRoomData[indexPath.row].messageCount if indexPath.row == 0 { // 이렇게 쓰다보면 재활용이 되어 속성이 남아있게 된다. (0번째 셀일때만 빨간색이 되도록 처리해보기!) cell.backgroundColor = .red } return cell // 테이블뷰에 넣을 셀 }
실제로 이렇게 코드를 작성하면 처음에는 잘 동작하지만 테이블뷰를 위아래로 내리면 셀이 큐에 들어갔다가 다른 indexPath.row로 재사용되면서 점점 빨간색 셀이 늘어나는 현상을 발견할 수 있다. (아래 티스토리 하단 부분 참고)
https://org9899.tistory.com/74[iOS] 4주차 세미나 정리
미션 검사 및 피드백 Q. present 방식에서 라이프 사이클이 호출이 안되는 문제 (viewWillDisappear이 호출안됨) A. .modalPresentationStyle = .fullscreen으로 변경해주면 호출되는걸 확인할 수 있음! or protoc..
org9899.tistory.com
이럴 때 간단하게 if 문에 else 구문을 추가해서 cell.backgroundColor = .clear 라는 식으로 색상 변경을 원하지 않는 row의 색상을 흰색으로 할 수 있지만, 큐에 들어가서 셀이 다시 처음처럼 비어져서 나오는 방식인 prepareForReuse() 메소드를 활용하는것이 더 좋다.
prepareForReuse()
공식문서를 보면 아래처럼 나와있다.
tableview 의 delegate가 셀을 재사용하도록 준비합니다.
UITableViewCell 객체가 재사용 가능한 경우 이 메서드는 UITableView 에 dequeueReusableCell (withIdentifier :) 메서드에서 객체가 반환되기 직전에 호출된다. 성능 상의 이유로 콘텐츠와 관련이 없는 셀 속성(예 : alpha, eiditing, 셀 선택 상태)만 reset해야하고, tableView (_ : cellForRowAt :)에 있는 테이블 뷰의 델리게이트는 셀을 재사용 할 때 항상 모든 콘텐츠를 reset해야한다.
설명을 보면 성능 상의 이유로 콘텐츠와 관련이 없는 셀 속성만 reset 해야 한다고 하고 tableView 에 있는 셀은 모든 콘텐츠를 reset해야 한다고 하는데 이 부분을 이용하여 해당 속성만 reset되도록 TableViewCell에 아래 코드를 추가해주었다.
override func prepareForReuse() { //super.prepareForReuse() self.backgroundColor = nil }
이 코드를 추가해주고 시연화면을 다시 확인해보면, 첫번째 셀에만 배경색이 빨간색으로 적용되는것을 확인할 수 있다.
https://developer-p.tistory.com/160
[iOS 스터디/week3-3] prepareForReuse() | 테이블뷰에서 Cell 속성이 임의로 변경되는 버그 해결방법. (Fixed
테이블뷰를 사용할 때 cell이 재사용되면서 속성이 임의로 변경되는 오류가 있습니다. 이번 글에선 테이블뷰에서 UISwitch의 isOn 속성이 임의로 변경되는 버그 해결하는 방법에 대해서 알려드리겠
developer-p.tistory.com
iOS 테이블뷰(UITableView) 셀의 재사용 — dequeueReusableCell
안녕하세요. 도미닉입니다.
kiljh.medium.com
https://developer.apple.com/documentation/uikit/uitableview/1614878-dequeuereusablecell
Apple Developer Documentation
developer.apple.com
https://developer.apple.com/documentation/uikit/uitableviewcell/1623223-prepareforreuse
Apple Developer Documentation
developer.apple.com
[Git]
- week4 참고
https://github.com/Eunice991217/UMC_3rd-iOS
GitHub - Eunice991217/UMC_3rd-iOS: sejong UMC 3rd iOS-study
sejong UMC 3rd iOS-study. Contribute to Eunice991217/UMC_3rd-iOS development by creating an account on GitHub.
github.com
좋아요2공유하기통계게시글 관리'iOS' 카테고리의 다른 글
[iOS] TableView Swipe 기능 구현 (0) 2022.10.30 [iOS] TableView를 이용한 메모장 만들기 (0) 2022.10.29 [iOS] 4주차 세미나 정리 (0) 2022.10.28 [iOS] 간단한 계산기 만들기 (0) 2022.10.06 [iOS] 3주차 세미나 정리 (2) 2022.10.03