본문 바로가기
Project/NETFLIX

NETFLIX CLONE 12편 (헤더뷰 랜덤기능, 상세 페이지 적용)

by 밤새는탐험가 2024. 5. 16.

✅ 헤더뷰에 랜덤 이미지 넣기 

✅ 업커밍, 서치컨트롤러에 상세 페이지 이동 기능 추가 

 


✅ 헤더뷰에 랜덤 이미지 넣기 

  • 헤더 뷰에 들어갈 이미지를 랜덤으로 뽑기 위한 변수 선언 
class HomeViewController: UIViewController {
    
    
    private var randomTrendingMovie: Title?
    private var headerView: HeroHeaderUIView?

 

 

  • 헤더 뷰에 표시할 이미지는 가장 인기 있는 영화로 채운다. 
    private func configureHeroHeaderView() {
        
        APICaller.shared.getTrendingMovies { [weak self] result in
            switch result {
            case .success(let titles):
                self?.randomTrendingMovie = titles.randomElement()
            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }

 

 

  • HeroHeaderView 파일 내에 랜덤으로 데이터 갖고온 거 설정하기 
    public func configure(with model: TitleViewModel) {
        
        guard let url = URL(string: "https://image.tmdb.org/t/p/w500/\(model.posterURL)") else { return }
        
        heroImageView.sd_setImage(with: url, completed: nil)
    }

 

 

  • configureHeroHeaderView() 함수 수정 
    private func configureHeroHeaderView() {
        
        APICaller.shared.getTrendingMovies { [weak self] result in
            switch result {
            case .success(let titles):
                
                let selectedTitle = titles.randomElement()
                
                self?.randomTrendingMovie = selectedTitle
                
                self?.headerView?.configure(with: TitleViewModel(titleName: selectedTitle?.original_title ?? "", posterURL: selectedTitle?.poster_path ?? "" ))
            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }

 

 

 

 

✅ 업커밍, 서치컨트롤러에 상세 페이지 이동 기능 추가 

  • extension UpcomingViewController 부분에 작성 
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let title = titles[indexPath.row]
        
        guard let titleName = title.original_title ?? title.original_name else { return }
        
        APICaller.shared.getMovie(with: titleName) { [weak self] result in
            switch result {
            case .success(let videoElement):
                DispatchQueue.main.async {
                    let vc = TitlePreviewViewController()
                    vc.configure(with: TitlePreviewViewModel(title: titleName, youtubeView: videoElement, titleOverview: title.overview ?? ""))
                    self?.navigationController?.pushViewController(vc, animated: true)
                }
                
            case.failure(let error):
                print(error.localizedDescription)
            }
        }
    }

 

 

 

  • SearchViewController 내에서 검색한 결과에 상세페이지 기능 적용 
  • 먼저 프로토콜 및 대리자 생성
import UIKit


protocol SearchResultsViewControllerDelegate: AnyObject {
    func SearchResultsViewcontrollerDidTapItem(_ viewModel: TitlePreviewViewModel)
}


class SearchResultsViewController: UIViewController {
    
    public var titles: [Title] = [Title]()
    
    public weak var delegate: SearchResultsViewControllerDelegate?

 

  • extension SearchResultsViewController 부분 작성 
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        collectionView.deselectItem(at: indexPath, animated: true)
        
        let title = titles[indexPath.row]
        
        guard let titleName = title.original_title ?? title.original_name else { return }
        
        APICaller.shared.getMovie(with: titleName) { [weak self] result in
            switch result {
            case .success(let videoElement):
                
                self?.delegate?.SearchResultsViewcontrollerDidTapItem(TitlePreviewViewModel(title: titleName, youtubeView: videoElement, titleOverview: title.overview ?? ""))
//                DispatchQueue.main.async {
//                    let vc = TitlePreviewViewController()
//                    vc.configure(with: TitlePreviewViewModel(title: titleName, youtubeView: videoElement, titleOverview: title.overview ?? ""))
//                    self?.navigationController?.pushViewController(vc, animated: true)
//                }
                
            case.failure(let error):
                print(error.localizedDescription)
            }
        }
        
    }

 

 

  • SearchViewController 내에 대리자 선언 및 함수 구현 
extension SearchViewController: UISearchResultsUpdating, SearchResultsViewControllerDelegate {
    
    
    func updateSearchResults(for searchController: UISearchController) {
        let searchBar = searchController.searchBar

        guard let query = searchBar.text,
              !query.trimmingCharacters(in: .whitespaces).isEmpty,
              query.trimmingCharacters(in: .whitespaces).count >= 2,
              let resultsController = searchController.searchResultsController as? SearchResultsViewController else { return }
        
        // 대리자 선언 
        resultsController.delegate = self
        
        APICaller.shared.search(with: query) { result in
            DispatchQueue.main.async {
                switch result {
                case.success(let titles):
                    
                    // resultsController 내의 titles 와 searchResultsCollectionView 경우에는 public으로 변경한다.
                    resultsController.titles = titles
                    resultsController.searchResultsCollectionView.reloadData()
                case.failure(let error):
                    print(error.localizedDescription)
                }
            }
        }
    }
    
    // 함수 구현 
    func SearchResultsViewcontrollerDidTapItem(_ viewModel: TitlePreviewViewModel) {
        
        DispatchQueue.main.async {
            let vc = TitlePreviewViewController()
            vc.configure(with: viewModel)
            self.navigationController?.pushViewController(vc, animated: true)
        }
    }
}

 

 

 

https://youtu.be/taDvp911ruQ?si=s3JMD-kA8BX_Y9Cf