📌 DetailViewController → SimilarTableViewCell → SimilarCollectionViewCell 데이터 흐름 정리
DetailViewController에서 유사한 영화와 TV 정보를 SimilarTableViewCell을 통해 UICollectionView 형태로 보여줌
SimilarCollectionViewCell을 통해 각 개별 콘텐츠(영화 또는 TV)를 셀에 표시
1️⃣ 구성 요소
- DetailViewController: 데이터를 가져와 UITableView의 SimilarTableViewCell에 전달
- SimilarTableViewCell: UICollectionView를 사용하여 SimilarCollectionViewCell을 보여줌
- SimilarCollectionViewCell: 영화 또는 TV 정보를 개별적으로 표시
📌 1. DetailViewController에서 데이터 가져오기 (fetchContentDetail)
class DetailViewController: UIViewController {
// MARK: - Variable
// 영화, TV와 유사한 정보 저장
private var contentSimilarInfo: HomeSection?
...
/// init으로 받아온 데이터를 통해 API 요청
private func fetchContentDetail() {
Task {
do {
// ✅ switch 문에서 데이터를 fetchedDetail 변수에 저장하고, 이후 한 번만 UI 업데이트를 수행
var fetchedDetail: ContentDetail?
var fetchedGenres: [String] = [] // 장르 저장 변수
var castingList: TopBilledCastInfoWelcome? // 출연진 목록 저장
var videoInfo: VideoInfoWelcome?
var posterInfo: PosterInfoWelcome?
var fetchedSimilarInfo: HomeSection?
switch contentType {
case .movie:
let movieDetail = try await NetworkManager.shared.getMovieDetailInfo(movieID: contentID)
fetchedDetail = .movie(movieDetail)
fetchedGenres = getGenresFromHomeSection(for: contentID)
castingList = try await NetworkManager.shared.getMovieCastInfo(contentID: contentID)
videoInfo = try await NetworkManager.shared.getMovieVideoInfo(contentID: contentID)
posterInfo = try await NetworkManager.shared.getMoviePosterInfo(contentID: contentID)
// ✅ 유사 정보 가져오기
let movieSimiliar = try await NetworkManager.shared.getMovieSimilarInfo(contentID: contentID)
fetchedSimilarInfo = .trendingMovies(movieSimiliar)
case .tv:
let tvDetail = try await NetworkManager.shared.getTVDetailInfo(tvID: contentID)
fetchedDetail = .tv(tvDetail)
fetchedGenres = getGenresFromHomeSection(for: contentID)
castingList = try await NetworkManager.shared.getTVCastInfo(contentID: contentID)
videoInfo = try await NetworkManager.shared.getTvVideoInfo(contentID: contentID)
posterInfo = try await NetworkManager.shared.getTvPosterInfo(contentID: contentID)
// ✅ 유사 정보 가져오기
let tvSimiliar = try await NetworkManager.shared.getTVSimilarInfo(contentID: contentID)
fetchedSimilarInfo = .trendingTVs(tvSimiliar)
case .people:
let peopleDetail = try await NetworkManager.shared.getPeopleDetailInfo(peopleID: contentID)
fetchedDetail = .people(peopleDetail)
fetchedGenres = getGenresFromHomeSection(for: contentID)
}
DispatchQueue.main.async {
self.detailTableHeaderView() // 헤더뷰 생성
// ✅ API 요청 실패 시 UI 업데이트 방지
guard let contentDetail = fetchedDetail else { return }
self.contentDetail = contentDetail
// ✅ 'CastingList'를 'switch' 문을 통해 저장
switch contentDetail {
case .movie:
if let castingList = castingList {
self.movieTopBilledCastInfo = .movie(castingList)
}
self.mediaVideos = videoInfo?.results ?? [] // ✅ 비디오 데이터 저장
self.mediaPosters = posterInfo?.posters ?? [] // ✅ 포스터 데이터 저장
// ✅ 유사 정보 저장
self.contentSimilarInfo = fetchedSimilarInfo
case .tv:
if let castingList = castingList {
self.movieTopBilledCastInfo = .tv(castingList)
}
self.mediaVideos = videoInfo?.results ?? [] // ✅ 비디오 데이터 저장
self.mediaPosters = posterInfo?.posters ?? [] // ✅ 포스터 데이터 저장
// ✅ 유사 정보 저장
self.contentSimilarInfo = fetchedSimilarInfo
case .people:
break
}
switch contentDetail {
case .movie(let movieDetail):
self.detailHeaderView?.configure(movieDetail, genres: fetchedGenres)
case .tv(let tvDetail):
self.detailHeaderView?.configure(tvDetail, genres: fetchedGenres)
case .people(let peopleDetail):
self.detailHeaderView?.configure(peopleDetail)
}
self.detailTableView.reloadData() // ✅ 데이터 로드되면 업데이트
}
} catch {
print("❌ 데이터 로드 실패1: \(error)")
}
}
}
🔹 설명
- NetworkManager를 사용해 getMovieSimilarInfo() 또는 getTVSimilarInfo() API를 호출하여 유사한 콘텐츠 데이터를 가져옴
- 가져온 데이터를 contentSimilarInfo에 저장
- detailTableView.reloadData()를 호출하여 테이블뷰 갱신
📌 2. DetailViewController에서 SimilarTableViewCell로 데이터 전달 (tableView(_:cellForRowAt:))
extension DetailViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return DetailSection.allCases.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// ✅ 현재 섹션 타입 가져오기
let sectionType = DetailSection.allCases[indexPath.section]
switch sectionType {
...
case .similar:
guard let cell = tableView.dequeueReusableCell(withIdentifier: SimilarTableViewCell.reuseIdentifier, for: indexPath) as? SimilarTableViewCell else { return UITableViewCell() }
if let contentSimilarInfo = contentSimilarInfo {
cell.configure(with: contentSimilarInfo) // ✅ SimilarTableViewCell에 데이터 전달
}
return cell
}
}
,,.
}
🔹 설명
- .similar 섹션이 호출되면 SimilarTableViewCell을 생성
- configure(with: contentSimilarInfo)를 호출하여 데이터를 넘겨줌
📌 3. SimilarTableViewCell에서 UICollectionView에 데이터 연결
class SimilarTableViewCell: UITableViewCell {
// MARK: - Variable
static let reuseIdentifier: String = "SimilarTableViewCell"
// ✅ 유사한 영화, tv 정보를 저장
private var contentSimilarInfo: HomeSection?
...
func configure(with contents: HomeSection) {
self.contentSimilarInfo = contents
similarCollectionView.reloadData() // ✅ UI 업데이트
}
...
🔹 설명
- DetailViewController에서 전달된 contentSimilarInfo를 저장
- similarCollectionView.reloadData()를 호출하여 UI를 업데이트
📌 4. SimilarTableViewCell에서 개별 데이터 전달 (cellForItemAt)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SimilarCollectionViewCell.reuseIdentifier, for: indexPath) as? SimilarCollectionViewCell else { return UICollectionViewCell() }
switch contentSimilarInfo {
case .trendingMovies(let movies):
let movie = movies[indexPath.item]
cell.configure(with: .movie(movie)) // ✅ 개별 영화 데이터 전달
case .trendingTVs(let tvs):
let tv = tvs[indexPath.item]
cell.configure(with: .tv(tv)) // ✅ 개별 TV 데이터 전달
case .trendingPeoples:
return UICollectionViewCell()
case .none:
return UICollectionViewCell()
}
return cell
}
🔹 설명
- contentSimilarInfo를 통해 trendingMovies 또는 trendingTVs에 접근하여 개별 데이터를 가져옴
- SimilarCollectionViewCell.configure(with:)를 호출하여 데이터를 전달
📌 5. SimilarCollectionViewCell에서 UI 설정 (configure(with:))
func configure(with content: SimilarContent) {
switch content {
case .movie(let movieResult):
if let posterPath = movieResult.backdropPath, !posterPath.isEmpty {
guard let url = URL(string: "https://image.tmdb.org/t/p/w500/\(posterPath)") else { return }
similarImageView.sd_setImage(with: url, completed: nil)
} else {
similarImageView.image = UIImage(systemName: "photo.badge.exclamationmark")
}
let title = movieResult.title
similarTitleLabel.text = title
let score = movieResult.voteAverage
scoreLabel.configure(with: score != 0 ? Int(score * 10) : 100)
case .tv(let tvResult):
if let posterPath = tvResult.backdropPath, !posterPath.isEmpty {
guard let url = URL(string: "https://image.tmdb.org/t/p/w500/\(posterPath)") else { return }
similarImageView.sd_setImage(with: url, completed: nil)
} else {
similarImageView.image = UIImage(systemName: "photo.badge.exclamationmark")
}
let name = tvResult.name
similarTitleLabel.text = name
let score = tvResult.voteAverage
scoreLabel.configure(with: score != 0 ? Int(score * 10) : 100)
}
}
🔹 설명
- SimilarContent을 통해 movieResult 또는 tvResult를 받아 UI를 설정
- 포스터 이미지와 제목, 평점을 설정하여 화면에 표시
⭐️ SimilarContent 열거형 생성하여 영화, tv 구분
- 새로운 Enum을 생성: 기존의 ContentDetail enum을 그대로 사용할 수 없으니, SimilarContent와 같은 새로운 enum을 만들어서 MovieResult와 TVResult를 처리할 수 있도록 한다.
- configure 메서드 오버로딩: SimilarCollectionViewCell에서 MovieResult와 TVResult를 처리할 수 있도록 configure(with content: SimilarContent)을 추가한다.
// 📌 유사한 콘텐츠를 위한 Enum 추가
enum SimilarContent {
case movie(MovieResult) // 영화 결과
case tv(TVResult) // TV 결과
}
✅ 최종 정리 - SimilarContent 생성 이유
- 기존의 ContentDetail는 MovieDetailInfoWelcome, TVDetailInfoWelcome을 다뤘음.
- 그러나 유사한 콘텐츠는 MovieResult, TVResult을 다룸 → 새 enum SimilarContent 생성
- 컬렉션뷰의 cellForItemAt에서 SimilarContent를 사용하여 configure 호출
- SimilarCollectionViewCell에서 configure(with content: SimilarContent)을 구현하여 데이터를 표시
'Project > MovieClip' 카테고리의 다른 글
thumnailImageView에서 .video 와 .poster 분기 처리하기 (0) | 2025.02.12 |
---|---|
📌 컬렉션 뷰에서 .video 아이템 클릭 시 YouTube 영상 재생하기 (0) | 2025.02.12 |
상세페이지에서 video, poster 데이터를 UICollectionView로 구현 (0) | 2025.02.11 |
헷갈리기 쉬운 주요 출연진 정보를 받아오는 로직 (0) | 2025.02.10 |
테이블의 rowheight을 동적으로 할 때 주의할 점 (0) | 2025.02.10 |