Swift

Swift + RxSwift | UITableView/ UICollectionView 에서 작동하는 델리게이트 메서드 willDisplayCell

ziziDev 2024. 12. 11. 08:19
반응형

 

willDisplayCell

 

 

UITableView 또는 UICollectionView에서 셀(Cell)이 화면에 표시되기 직전에 호출되는 delegate 메서드입니다. 이 메서드는 셀이 사용자에게 보이기 전에 레이아웃을 미리 구성하거나 애니메이션을 추가하는 경우에 자주 사용됩니다.

 

willDisplayCell의 동작 방식

  • 언제 호출되나요?
    • 사용자가 스크롤하여 새로운 셀이 화면에 표시되기 직전에 호출됩니다.

  • 어디에 사용되나요?
    • UITableViewDelegate의 tableView(_:willDisplay:forRowAt:) 메서드
    • UICollectionViewDelegate의 collectionView(_:willDisplay:forItemAt:) 메서드
  • 주로 어떤 작업에 사용되나요?
    • 셀 애니메이션: 셀이 화면에 나타날 때 페이드 인, 슬라이드 인 등의 애니메이션을 적용할 때 사용합니다.
    • Infinite Scroll: 무한 스크롤을 구현할 때, 마지막 셀이 화면에 표시되었을 때 API 호출을 트리거하는 데 사용합니다.
    • 레이아웃 최적화: 셀의 모양을 미리 설정하거나 콘텐츠를 미리 로드합니다.
    • 데이터 바인딩: 셀이 나타날 때 데이터를 연결하고 뷰의 상태를 업데이트합니다.

 

RxSwift에서 willDisplayCell

RxSwift에서는 이 기능을 Reactive 방식으로 변환하여 사용할 수 있습니다. RxCocoa 라이브러리를 사용하면 테이블 뷰나 컬렉션 뷰의 willDisplayCell 이벤트를 Observable로 변환할 수 있습니다.

 

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    let disposeBag = DisposeBag()
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 셀 표시 직전의 이벤트를 구독
        tableView.rx.willDisplayCell
            .subscribe(onNext: { (cell, indexPath) in
                print("📦 willDisplayCell: \(indexPath.row) 번째 셀이 표시됩니다.")
                // 셀에 애니메이션 추가 (예: 투명도 0에서 1로 페이드 인)
                cell.alpha = 0
                UIView.animate(withDuration: 0.3) {
                    cell.alpha = 1
                }
            })
            .disposed(by: disposeBag)
    }
}

 

RxCocoa의 willDisplayCell

RxCocoa는 UITableView 또는 UICollectionView의 willDisplayCell을 Rx Observable로 변환해줍니다.

📌 RxCocoa의 willDisplayCell 시그니처

public var willDisplayCell: ControlEvent<(cell: UITableViewCell, indexPath: IndexPath)>

 

활용 사례

페이징 스크롤 (Infinite Scroll)

  • 사용자가 마지막 셀에 도달했을 때 API 호출을 트리거하기 위해 사용합니다.
tableView.rx.willDisplayCell
    .subscribe(onNext: { (cell, indexPath) in
        let totalItems = 100 // 예시로 총 100개의 아이템이 있다고 가정
        if indexPath.row == totalItems - 1 { 
            print("🚀 마지막 셀이 표시되었습니다. 다음 페이지 로드 중...")
            // 다음 페이지의 데이터를 로드하는 함수 호출
        }
    })
    .disposed(by: disposeBag)

 

셀 애니메이션 추가

  • 셀이 처음 나타날 때 애니메이션을 추가하는 경우입니다.
tableView.rx.willDisplayCell
    .subscribe(onNext: { (cell, indexPath) in
        cell.transform = CGAffineTransform(translationX: 0, y: 50)
        UIView.animate(withDuration: 0.3) {
            cell.transform = .identity
        }
    })
    .disposed(by: disposeBag)

 

RxCocoa의 다른 관련 메서드

didEndDisplayingCell 셀이 화면에서 사라질 때 호출됩니다.
willDisplayCell 셀이 화면에 보이기 직전에 호출됩니다.
itemSelected 셀이 선택되었을 때 호출됩니다.
itemDeselected 셀 선택이 해제되었을 때 호출됩니다.
modelSelected 셀과 함께 연결된 데이터 모델을 제공합니다.

 

📢 정리

  • **willDisplayCell**은 셀이 화면에 보이기 직전에 호출되며, 레이아웃, 데이터 로드, 애니메이션 추가에 자주 사용됩니다.
  • RxCocoa의 **tableView.rx.willDisplayCell**은 Observable로 전환하여 반응형 프로그래밍 스타일로 사용합니다.
  • 무한 스크롤, 레이아웃 조정, 셀 애니메이션 추가 등 다양한 작업에 활용됩니다.

💡 질문 예시

  • Q: willDisplayCell과 didEndDisplayingCell의 차이점은?
    • A: willDisplayCell은 셀이 보이기 직전에 호출되고, didEndDisplayingCell은 셀이 화면에서 사라진 직후 호출됩니다.
  • Q: RxCocoa 없이도 무한 스크롤을 구현할 수 있나요?
    • A: 가능합니다. 하지만 RxCocoa의 willDisplayCell Observable을 사용하면 더 간결하고 직관적인 코드를 작성할 수 있습니다.
  • Q: Infinite Scroll에서 마지막 셀을 어떻게 인식하나요?
    • A: indexPath.row == totalItemCount - 1 조건으로 마지막 셀에 도달했는지 확인할 수 있습니다.
  • Q: 셀 애니메이션이 버벅거리는 경우 어떻게 최적화할 수 있나요?
    • A: 애니메이션 효과를 최소화하거나, CATransaction으로 레이아웃을 배치하고 애니메이션 블록을 최적화할 수 있습니다.
반응형