일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- WWDC22
- Sendbird
- backend
- Project
- widgetkit
- Coding Test
- swift concurrency
- SwiftUI
- Firebase
- cloud functions
- coreml
- Swift
- Flutter
- github
- createml
- watchkit
- UITableView
- tabman
- Delegate Pattern
- task.yield()
- 코테
- ios
- app intents
- UIStackView
- UIDatePicker
- Apple Developer Academy
- Complication
- spring
- Tuist
- fcm
- Today
- Total
azhy의 iOS 이야기
[iOS/Swift] UITableView, 셀 재사용 시 발생하는 문제 본문
2022년 7월 5일에 작성됨
개인 프로젝트를 하고 있는데 tableView를 사용하는 도중 내가 예상한 결과와 다른 화면이 나오는 문제가 생겼습니다.
원래 결과는 30일까지만 text가 회색이고 나머지 뒤에 text는 검은색이어야 정상적은 결과지만 보시다시피 중간에 뜬금없이 200일, 300일, 1주년, 400일 text가 회색으로 표시되고 있었습니다.
그래서 cell에 들어가는 data가 문제인가 싶어서 print를 찍어봤지만 데이터에는 문제가 없었어요.. 무엇이 문제인지 찾다가 결국 알아내서 한번 정리해보려 합니다.
dequeueReusableCell
tableView를 사용한 경험이 있으면 어디선가 봤을 법한 코드입니다. 애플 공식 문서에 따르면 "성능상의 이유로 테이블 보기의 데이터 원본은 일반적으로 메서드의 행에 셀을 할당할 때 개체를 재사용해야 합니다.... 이 메서드는 기존 셀이 사용 가능한 경우 큐에서 빼거나 이전에 등록한 클래스 또는 nib 파일을 사용하여 새 셀을 만듭니다...." 요정도만 읽어봐도 머릿속으로 대충 이해가 갑니다.
한마디로 이전에 사용한 셀이 있으면 큐에서 꺼내서 재사용하고 셀이 없으면 새로 만든다. 요런 느낌이다.
그림을 통해 알아보면 tableView가 위로 스크롤되어 사라지게 되는 셀은 큐에 들어가고 맨 앞에 있던 큐가 새롭게 보이는 셀, 맨 하단에서 올라오게 되는 셀로 사용됩니다.
그래서 제가 진행한 프로젝트에서도 셀에 들어가는 내용은 다르지만 셀 자체는 재사용되기 때문에 text color, aplha, backgroundColor 등 내용과는 다른 것들은 원치 않는 곳에서 재사용될 수 있었던 것이죠
prepareForeReuse
그럼 위에 문제를 해결할 수 있는 방법은 없냐? prepareForeReuse 메서드를 사용하면 됩니다. prepareForeReuse 메서드는 셀을 초기화시켜 주는 메서드인데 애플 공식 문서에 따르면 "객체에 재사용 식별자가 있는 경우 테이블 뷰는 메서드에서 객체를 반환하기 직전에 이 메서드를 호출합니다. 내용과는 관련이 없는 셀의 속성만 재설정해야 합니다...."라고 적혀있네요.
그림을 보면 cellForRowAt, 하단에 셀을 보이기 직전에 prepareForReuse() 메서드가 실행되는 모습을 볼 수 있습니다. 그래서 우리는 요 메서드를 이용하여 본인이 원하는 셀의 값에 초기화를 시켜주면 원하는 결과화면을 볼 수 있습니다.
prepareForReuse() 사용할 때 재사용되는 모든 셀에 대하여 초기화시키면 앞에 이미 처리된 셀들 (어떤 값을 통한 체크박스나 color 처리 등) 또한 모두 초기화되기 때문에 앞에서 어떤 데이터를 이용하여 따로 결과를 보여줘야 하는 셀들에 대해서는 데이터를 확인해서 정상적인 화면으로 보이게 따로 처리해줘야 합니다.
결과
// StoryCell.swift
override func prepareForReuse() {
super.prepareForReuse()
self.storyDayText.textColor = .black
}
저는 간단하게 textColor 만 바꾸면 됐었기에 prepareForReuse() 메서드에 textColor를 black으로 초기화시켜주었습니다.
여기에 초기화시키는 코드나 데이터를 확인해서 셀을 수정하는 코드가 들어가면 될 것 같네요. 이렇게 수정하니 이제 원하는 결과가 나오는 것을 볼 수 있었습니다.
'Swift' 카테고리의 다른 글
[iOS/Swift] dismiss 하고 present 넘어가기 (Presented vs Presenting ViewController) (0) | 2024.11.12 |
---|---|
[iOS/Swift] UITableView scrollToRow, 특정 셀로 스크롤 이동 (0) | 2024.11.12 |
[iOS/Swift] View와 Button 에 click action 등록하기 (0) | 2024.11.12 |
[iOS/Swift] delegate pattern, 데이터 주고 받기 (0) | 2024.11.11 |
[iOS/Swift] ViewController 생명주기 (0) | 2024.11.11 |