아무튼 더 해보자
더하기도 해보고 더 공부도 하고
TableView안에 CollectionView를 넣어보자 (ex) Netflix, banner 광고)
TableView 안에 CollectionView를 잘 보면 똑같은 셀이 계속 재사용 되는 것을 볼 수 있다.
UIView Xib를 만들어주자
사이즈를 자유롭게 지정하려면 Size는 Freeform으로 Safe Area Layout Guide는 해제해주자
View를 재사용할 것이기 때문에 View자체에 UIView를 지정하는게 아니라 File's Owner에 UIView를 지정해준다
Class 부분에 UIView를 지정해준 것이 보인다
항상 그랬듯이 ImageView의 IBoutlet을 연결 해준 후 사용하려면 오류가 발생한다
import UIKit
class MovieCardView: UIView {
@IBOutlet weak var posterImageView: UIImageView!
required init?(coder: NSCoder) {
super.init(coder: coder)
let view = UINib(nibName: "MovieCardView", bundle: nil).instantiate(withOwner: self).first as! UIView
view.frame = bounds
view.backgroundColor = .clear
self.addSubview(view)
}
}
Xib에서는 xml형식으로 IB(interface builder)의 형태로 가지고 있지만 compile 하면 Nib 파일로 변환되기 때문에 사용자의 화면에 출력하려면 init(coder: NSCoder)를 통해 객체를 생성 해주어야한다
재사용 할 View는 준비가 되었다. 이제 TableView + CollectionView를 만들어 보자
아까 만들어 놓은 재사용 View를 CollectionView 안에서 사용하기 위해 CollectionViewCell에 쓰일 UIView를 만들고 아까 만든 재사용 View를 상속한다
import UIKit
class MovieCardCollectionViewCell: UICollectionViewCell {
static let identifier = "MovieCardCollectionViewCell"
@IBOutlet weak var movieCardView: MovieCardView!
override func awakeFromNib() {
super.awakeFromNib()
setupUI()
}
// override func prepareForReuse() {
// super.prepareForReuse()
//
// movieCardView.contentLabel.text = "Being Ready"
// }
func setupUI() {
movieCardView.backgroundColor = .clear
movieCardView.posterImageView.backgroundColor = .lightGray
}
}
UICollectionViewCell에서 사용될 Cell의 UI를 설정해준다 prepareForReuse와 awakeFromNib은 다음 포스팅에서 설명하겠다
위의 화면을 보면 TableView안에 CollectionView가 있는 형태 즉 TableViewCell 안에 CollectionView가 있는 형태이다
TableViewCell을 만들어 주자
class MovieCardTableViewCell: UITableViewCell {
static let identifier = "MovieCardTableViewCell"
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var movieCollectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
setupUI()
}
func setupUI() {
titleLabel.font = .boldSystemFont(ofSize: 24)
titleLabel.text = "아는 와이프와 비슷한 콘텐츠"
titleLabel.backgroundColor = .black
titleLabel.textColor = .white
movieCollectionView.backgroundColor = .clear
movieCollectionView.collectionViewLayout = collectionViewLayout()
}
func collectionViewLayout() -> UICollectionViewFlowLayout {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: 300, height: 180)
layout.minimumLineSpacing = 16
layout.minimumInteritemSpacing = 16
layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 0)
return layout
}
}
CollectionView를 IBoutlet으로 연결하고 위의 화면처럼 Lable하나도 지정하고 CollectionViewCell처럼 UI를 설정해준다
이제 재료는 다 준비 되었으니 User들이 보는 화면을 만들어야 한다
import UIKit
import Kingfisher
class MovieCardViewController: UIViewController {
@IBOutlet weak var mainTableView: UITableView!
var recommendList: [[String]] = []
override func viewDidLoad() {
super.viewDidLoad()
mainTableView.delegate = self
mainTableView.dataSource = self
TMDBAPIManager.shared.requestImage { recommend in
self.recommendList = recommend
self.mainTableView.reloadData()
}
}
}
extension MovieCardViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return recommendList.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: MovieCardTableViewCell.identifier, for: indexPath) as? MovieCardTableViewCell else { return UITableViewCell() }
cell.backgroundColor = .clear
cell.movieCollectionView.backgroundColor = .clear
cell.movieCollectionView.delegate = self
cell.movieCollectionView.dataSource = self
cell.movieCollectionView.register(UINib(nibName: MovieCardCollectionViewCell.identifier, bundle: nil), forCellWithReuseIdentifier: MovieCardCollectionViewCell.identifier)
cell.movieCollectionView.tag = indexPath.section
cell.movieCollectionView.reloadData()
cell.titleLabel.text = "\(TMDBAPIManager.shared.movieList[indexPath.section].0) Similar Contents!"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 240
}
}
extension MovieCardViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return recommendList[collectionView.tag].count
//return numberList[collectionView.tag].count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MovieCardCollectionViewCell.identifier, for: indexPath) as? MovieCardCollectionViewCell else { return UICollectionViewCell()}
cell.movieCardView.posterImageView.backgroundColor = .black
cell.movieCardView.posterImageView.contentMode = .scaleToFill
let url = URL(string: "\(TMDBAPIManager.shared.imageURL)\(recommendList[collectionView.tag][indexPath.item])")
cell.movieCardView.posterImageView.kf.setImage(with: url)
return cell
}
func collectionViewLayout() -> UICollectionViewFlowLayout {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
return layout
}
}
Tmdb에서 API 통신을 받아온 후(이전 게시물에서 API통신 포스팅을 보면 활용할 수 있다) 구현했다
지금까지 해온 작업을 하나로 합치는 과정이라 순서가 헷갈리거나 넣어야 할 곳에 안넣는 상황이 발생할 수 있지만 조금만 생각해보면 이전 작업의 총합으로 확장을 시킨 것 뿐이다
'Tech > iOS' 카테고리의 다른 글
[iOS]Day38 - Privacy (0) | 2022.08.11 |
---|---|
[iOS]Day37 - AwakeFromNib, PrepareForReuse (0) | 2022.08.10 |
[iOS]Day37 - IBInspectable/IBDesignable (0) | 2022.08.09 |
[iOS]Day36 - AutomaticDimenssion (0) | 2022.08.08 |
[iOS]Day 32 - Pagenation (0) | 2022.08.04 |