🎬 배우 출연작(Credit) 섹션의 구조 정리 및 데이터 흐름
✅ 전체적인 흐름
- PeopleDetatilViewController에서 viewDidLoad()에서 API를 호출하여 배우의 영화 및 TV 출연작 데이터를 가져온다.
- 출연작 데이터는 movieCredits, tvCredits 배열에 저장된다.
- CreditTableViewCell에서 기본적으로 영화(Movie) 출연작을 표시하고, 버튼을 눌러 TV 출연작으로 변경할 수 있다.
- CreditTableViewCell 내부의 UICollectionView에서 출연작을 수평 스크롤로 표시한다.
- 컬렉션뷰 아이템을 선택하면 해당 작품의 상세페이지(DetailViewController)로 이동한다.
✅ 구현된 주요 로직 정리
1. PeopleDetatilViewController에서 API 요청하여 데이터 저장
- movieCredits & tvCredits 배열에 각각 영화와 TV 출연작 데이터를 저장.
- API 호출이 완료되면 tableView.reloadData() 실행.
class PeopleDetatilViewController: UIViewController {
private let peopleID: Int
// ✅ 영화, 티비 출연작 저장
private var movieCredits: [MovieCreditCast] = []
private var tvCredits: [TVCreditCast] = []
private var creditType: CreditType = .movie // ✅ 기본값: Movie
override func viewDidLoad() {
super.viewDidLoad()
fetchedPeopleDetailInfo() // API 요청
}
private func fetchedPeopleDetailInfo() {
Task {
do {
// ✅ 영화, 티비 API 요청 ➡️ 저장
let movieCredits = try await NetworkManager.shared.getMovieCredits(peopleID: peopleID)
let tvCredits = try await NetworkManager.shared.getTVCredits(peopleID: peopleID)
DispatchQueue.main.async { [self] in
self.movieCredits = movieCredits.cast
self.tvCredits = tvCredits.cast
self.peopleTableView.reloadData()
}
} catch {
print("❌ 데이터 로드 실패: \(error)")
}
}
}
}
2. PeopleDetatilViewController에서 UITableView 설정
- 영화 또는 TV 출연작을 CreditTableViewCell에 전달.
extension PeopleDetatilViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch PeopleDetailSection.allCases[indexPath.section] {
case .overview:
let cell = tableView.dequeueReusableCell(withIdentifier: PeopleOverviewTableViewCell.reuseIdentifier, for: indexPath) as! PeopleOverviewTableViewCell
cell.configure(with: koreanBio)
return cell
// ✅ 출연작에 데이터 전달
case .filmography:
let cell = tableView.dequeueReusableCell(withIdentifier: CreditTableViewCell.reuseIdentifier, for: indexPath) as! CreditTableViewCell
switch creditType {
case .movie:
cell.configure(with: .movie(movieCredits), creditType: .movie)
case .tv:
cell.configure(with: .tv(tvCredits), creditType: .tv)
}
cell.delegate = self
return cell
}
}
}
3. CreditTableViewCell에서 데이터 처리 및 UI 구성
- configure()에서 CreditInfos에 따라 영화 또는 TV 데이터를 설정하고 컬렉션뷰를 리로드.
- didTapCalledMovie() & didTapCalledTV() 클릭 시 delegate?.didTapCategoryButton() 호출.
class CreditTableViewCell: UITableViewCell {
// MARK: - Variable
static let reuseIdentifier: String = "CreditTableViewCell"
// ✅ 현재 선택된 카테고리 관리
private var creditType: CreditType = .movie
// ✅ CreditTableViewCell에 전달할 데이터 형식
private var creditItems: CreditInfos?
weak var delegate: CreditTableViewCellDelegate?
// MARK: - UI Component
private lazy var calledMovieCreditButton: UIButton = categoryButton(with: "Movie", action: #selector(didTapCalledMovie))
private lazy var calledTVCreditButton: UIButton = categoryButton(with: "TV", action: #selector(didTapCalledTV))
private let creditCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: 250, height: 180)
layout.minimumLineSpacing = 10
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
return collectionView
}()
// MARK: - Init
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(buttonStackView)
contentView.addSubview(creditCollectionView)
setupCollectionViewDelegate()
}
// MARK: - Function
func configure(with creditInfos: CreditInfos, creditType: CreditType) {
self.creditItems = creditInfos
self.creditType = creditType
DispatchQueue.main.async {
self.creditCollectionView.reloadData()
self.updateButtonState()
}
}
private func updateButtonState() {
UIView.animate(withDuration: 0.3) { [self] in
switch creditType {
case .movie:
calledMovieCreditButton.configuration?.baseBackgroundColor = .systemBlue
calledTVCreditButton.configuration?.baseBackgroundColor = .systemGray
case .tv:
calledMovieCreditButton.configuration?.baseBackgroundColor = .systemGray
calledTVCreditButton.configuration?.baseBackgroundColor = .systemBlue
}
}
}
// MARK: - Action
@objc private func didTapCalledMovie() {
delegate?.didTapCategoryButton()
}
@objc private func didTapCalledTV() {
delegate?.didTapCategoryButton()
}
}
4. CreditCollectionViewCell에서 개별 아이템 표시
- CreditCollectionViewCell에서 영화 또는 TV 아이템을 표시하고 클릭 시 didTapImage()를 실행.
class CreditCollectionViewCell: UICollectionViewCell {
static let reuseIdentifier: String = "CreditCollectionViewCell"
private var selectedContentId: Int?
private var selectedContentType: ContentType?
weak var delegate: CreditCollectionViewCellDelegate?
func configure(with content: CreditInfo) {
switch content {
case .movie(let movieDetail):
self.selectedContentId = movieDetail.id
self.selectedContentType = .movie
case .tv(let tvDetail):
self.selectedContentId = tvDetail.id
self.selectedContentType = .tv
}
}
@objc private func didTapCreditImage() {
guard let selectedContentId = selectedContentId, let selectedContentType = selectedContentType else { return }
delegate?.didTapImage(with: selectedContentId, contentType: selectedContentType)
}
}
5. PeopleDetatilViewController에서 델리게이트 처리
- didTapCategoryButton()에서 creditType.toggle()을 통해 영화/TV 전환.
- didTapImage()에서 DetailViewController로 이동.
extension PeopleDetatilViewController: CreditTableViewCellDelegate {
func didTapCategoryButton() {
creditType.toggle() // Movie ↔ TV 전환
DispatchQueue.main.async {
self.peopleTableView.reloadData()
}
}
func didTapImage(with contentID: Int, contentType: ContentType) {
let detailVC = DetailViewController(contentID: contentID, contentType: contentType)
navigationController?.pushViewController(detailVC, animated: true)
}
}
🎬 출연작 데이터 관리 및 구분하는 enum 설명
✅ CreditType, CreditInfos, CreditInfo의 역할
배우의 출연작 데이터는 영화(Movie) 와 TV(TV Show) 로 나뉜다.
이 데이터를 구분하고, UITableView 및 UICollectionView에서 동적으로 처리하기 위해 열거형(enum)을 사용한다.
enum CreditType {
case movie
case tv
mutating func toggle() {
self = (self == .movie) ? .tv : .movie
}
}
📌 역할
- 현재 CreditTableViewCell에서 표시할 출연작이 영화인지, TV인지 구분하는 현재 선택된 상태.
- toggle() 메서드를 사용하여 영화 <-> TV 전환이 가능.
var creditType: CreditType = .movie
creditType.toggle() // 현재 타입이 movie라면 tv로 변경, tv라면 movie로 변경
print(creditType) // tv
🏗 어디서 사용되는가?
- PeopleDetatilViewController에서 creditType을 저장하고 있음.
- didTapCategoryButton()에서 creditType.toggle()을 실행하여 영화/TV를 전환.
- CreditTableViewCell에서 creditType을 기반으로 configure()에서 데이터 설정.
✅ 2. CreditInfos - CreditTableViewCell에 전달할 데이터 형식
enum CreditInfos {
case movie([MovieCreditCast])
case tv([TVCreditCast])
}
📌 역할
- CreditTableViewCell에서 영화 목록 또는 TV 목록을 받을 때 사용.
- API에서 가져온 데이터를 영화 리스트 또는 TV 리스트로 감싸서 CreditTableViewCell로 전달.
let movieList: [MovieCreditCast] = [...] // API에서 받은 영화 출연작 배열
let creditInfo = CreditInfos.movie(movieList)
🏗 어디서 사용되는가?
- PeopleDetatilViewController에서 출연작 데이터를 CreditTableViewCell로 전달할 때 사용.
- CreditTableViewCell의 configure()에서 이 타입을 기준으로 컬렉션뷰를 업데이트.
✅ 3. CreditInfo - CreditCollectionViewCell에서 개별 아이템을 저장
enum CreditInfo {
case movie(MovieCreditCast)
case tv(TVCreditCast)
}
📌 역할
- UICollectionView의 개별 셀에서 해당 아이템이 영화인지, TV인지 구분.
- CreditCollectionViewCell에서 사용하여 개별 아이템을 표시.
'Project > MovieClip' 카테고리의 다른 글
❌ 문제 발생... UICollectionViewDiffableDataSource.. 데이터 중복으로 인한 데이터 누락 (0) | 2025.02.20 |
---|---|
⭐️ 버튼의 애니메이션 효과 주기 (0) | 2025.02.18 |
🔥 배우의 영어로된 소개글을 한글로 번역하기 (1) | 2025.02.15 |
🤔 배우 프로필의 소개 부분 "더보기" "접기" 기능 구현 (1) | 2025.02.14 |
배우의 소셜 미디어 계정을 가져오는 방법 🤔 (0) | 2025.02.14 |