✅ 영화 상세 페이지 제작
- 상세 페이지 생성
- 상세 페이지에 전달하기 위한 ViewModel 생성
- 상세 페이지에 데이터를 전달하는 함수 구현
- 데이터 전달을 위한 델리게이트 패턴 적용
✅ 영화 상세 페이지 제작
- TitlePreviewViewController 파일 생성
- Home 화면에서 영화를 누르면 해당 영화에 대한 예고편과 영화 이름 그리고 개요가 나오게 함
import UIKit
import WebKit
class TitlePreviewViewController: UIViewController {
private let webView: WKWebView = {
let webView = WKWebView()
webView.translatesAutoresizingMaskIntoConstraints = false
return webView
}()
private let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = .systemFont(ofSize: 22, weight: .bold)
label.text = "Harry Potter"
return label
}()
private let overviewLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.font = .systemFont(ofSize: 18, weight: .bold)
label.numberOfLines = 0
label.text = "This is the best movie "
return label
}()
private let downloadButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .red
button.setTitle("Download", for: .normal)
button.setTitleColor(.label, for: .normal)
button.layer.cornerRadius = 10
button.layer.masksToBounds = true
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
view.addSubview(webView)
view.addSubview(titleLabel)
view.addSubview(overviewLabel)
view.addSubview(downloadButton)
configureConstraints()
}
func configureConstraints() {
let webViewConstraints = [
webView.topAnchor.constraint(equalTo: view.topAnchor, constant: 50),
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
webView.heightAnchor.constraint(equalToConstant: 250)
]
let titleLabelConstraints = [
titleLabel.topAnchor.constraint(equalTo: webView.bottomAnchor, constant: 20),
titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20)
]
let overviewLabelConstraints = [
overviewLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 15),
overviewLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20)
]
let downloadButtonConstraints = [
downloadButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
downloadButton.topAnchor.constraint(equalTo: overviewLabel.bottomAnchor, constant: 25),
downloadButton.widthAnchor.constraint(equalToConstant: 140),
downloadButton.heightAnchor.constraint(equalToConstant: 40)
]
NSLayoutConstraint.activate(webViewConstraints)
NSLayoutConstraint.activate(titleLabelConstraints)
NSLayoutConstraint.activate(overviewLabelConstraints)
NSLayoutConstraint.activate(downloadButtonConstraints)
}
}
- ViewModel 폴더 내에 TitlePreviewViewModel 이라는 데이터 모델 생성
import Foundation
struct TitlePreviewViewModel {
let title: String
let youtubeView: VideoElement
let titleOverview: String
}
- TitlePreviewViewController 내에 데이터를 받아올 함수 구현
// 데이터 불러오기
func configure(with model: TitlePreviewViewModel) {
titleLabel.text = model.title
overviewLabel.text = model.titleOverview
guard let url = URL(string:"http://www.youtube.com/embed/\(model.youtubeView.id.videoId)") else { return }
webView.load(URLRequest(url: url))
}
- CollectionViewTableViewCell 파일에 프로토콜 생성
- 델리게이트 패턴을 사용하여 데이터 전달 목적
protocol CollectionViewTableViewCellDelegate: AnyObject {
func CollectionViewTableViewCellDidTapCell(_ cell: CollectionViewTableViewCell, viewModel: TitlePreviewViewModel)
}
- 대리자 변수 선언
class CollectionViewTableViewCell: UITableViewCell {
static let identifier = "CollectionViewTableViewCell"
// 데이터 전달을 위한 대리자 선언
weak var delegate: CollectionViewTableViewCellDelegate?
- collectionView 내의 세을 선택하면 결과를 반영하는 함수 구현
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 + " trailer") { result in
switch result {
case .success(let videoElement):
let title = self.titles[indexPath.row]
guard let titleOverview = title.overview else { return }
let viewModel = TitlePreviewViewModel(title: titleName, youtubeView: videoElement, titleOverview: titleOverview)
self.delegate?.CollectionViewTableViewCellDidTapCell(self, viewModel: viewModel)
case .failure(let error):
print(error.localizedDescription)
}
}
}
- 홈뷰컨트롤러에서 데이터를 불러오는 함수구현
extension HomeViewController: CollectionViewTableViewCellDelegate {
func CollectionViewTableViewCellDidTapCell(_ cell: CollectionViewTableViewCell, viewModel: TitlePreviewViewModel) {
DispatchQueue.main.async { [weak self] in
let vc = TitlePreviewViewController()
vc.configure(with: viewModel)
self?.navigationController?.pushViewController(vc, animated: true)
}
}
}
- TitlePreviewViewController 내에 delegate 라는 변수에 접근하기 위해 cell 에 접근이 가능한 tableView 메서드에 접근
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
// 전체 셀 갯수
func numberOfSections(in tableView: UITableView) -> Int {
return sectionTitles.count
}
// 각 셀에 들어갈 셀의 갯수
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: CollectionViewTableViewCell.identifier, for: indexPath) as? CollectionViewTableViewCell else { return UITableViewCell() }
cell.delegate = self
https://youtu.be/Wg19HLoG6ac?si=9lzlEctmMopI4X3Q
\
'Project > NETFLIX' 카테고리의 다른 글
NETFLIX CLONE 13편 (코어 데이터) (0) | 2024.05.16 |
---|---|
NETFLIX CLONE 12편 (헤더뷰 랜덤기능, 상세 페이지 적용) (0) | 2024.05.16 |
NETFLIX CLONE 10편 (유튜브 API 갖고오기) (0) | 2024.05.14 |
NETFLIX CLONE 9편 (Search) (0) | 2024.05.11 |
NETFLIX CLONE 8편 (업커밍 관련 뷰 생성) (0) | 2024.05.09 |