Building Spotify App in Swift 5 & UIKit - Part 10 (Xcode 12, 2021, Swift 5) - Build App
Browse UI 2
와 마찬가지로 커스텀 컬렉션 뷰 셀 구현struct FeaturedPlaylistCellViewModel {
let name: String
let artworkURL: URL?
let creatorName: String
}
struct RecommendedTrackCellViewModel {
let name: String
let artistName: String
let artworkURL: URL?
}
sections.append(.featuredPlaylists(viewModels: playlists.compactMap({ playlist in
return FeaturedPlaylistCellViewModel(name: playlist.name, artworkURL: URL(string:playlist.images.first?.url ?? ""), creatorName: playlist.owner.display_name)
})))
sections.append(.recommendedTracks(viewModels: tracks.compactMap({ track in
return RecommendedTrackCellViewModel(name: track.name, artistName: track.artists.first?.name ?? "-", artworkURL: URL(string: track.album.images.first?.url ?? ""))
})))
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let type = sections[indexPath.section]
switch type {
...
case .featuredPlaylists(viewModels: let viewModels):
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FeaturedPlaylistCollectionViewCell.identifier, for: indexPath) as? FeaturedPlaylistCollectionViewCell else {
return UICollectionViewCell()
}
let viewModel = viewModels[indexPath.row]
cell.configure(with: viewModel)
return cell
case .recommendedTracks(viewModels: let viewModels):
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: RecommendedTrackCollectionViewCell.identifier, for: indexPath) as? RecommendedTrackCollectionViewCell else {
return UICollectionViewCell()
}
let viewModel = viewModels[indexPath.row]
cell.configure(with: viewModel)
return cell
}
}
configure
함수로 셀 UI 패치 → 해당 셀을 리턴import UIKit
import SDWebImage
class FeaturedPlaylistCollectionViewCell: UICollectionViewCell {
static let identifier = "FeaturedPlaylistCollectionViewCell"
private let playlistCoverImageView: UIImageView = {
// imageView
}()
private let playlistNameLabel: UILabel = {
// label
}()
private let creatorNameLabel: UILabel = {
// label
}()
...
override func layoutSubviews() {
// UI layout
}
override func prepareForReuse() {
super.prepareForReuse()
playlistCoverImageView.image = nil
playlistNameLabel.text = nil
creatorNameLabel.text = nil
}
func configure(with viewModel: FeaturedPlaylistCellViewModel) {
playlistCoverImageView.sd_setImage(with: viewModel.artworkURL, completed: nil)
playlistNameLabel.text = viewModel.name
creatorNameLabel.text = viewModel.creatorName
}
}
configure
함수 호출 시 뷰 모델의 데이터에 따라 자동으로 셀 UI가 그려짐prepareForReuse
함수가 호출되기 때문에 해당 데이터에 널을 할당, 메모리 낭비를 방지첫 번째 섹션을 그리는 로직과 동일한 방법으로 두 번째, 세 번째 섹션을 그린다.
configure
하는 코드를 작성하자!x
, y
를 통해 줄 수도 있고, 오토 레이아웃에 false
를 주고 anchor
를 통해 조정할 수도 있다. 편리한 방식대로 구현하자.prepareForUse
함수를 오버라이드, 해당 셀이 재사용될 때 본 셀에 '들어갔던' 데이터 값(이미 바인딩하여 스크린에 보이는)에 널 값을 주어 해제하는 게 중요한 방법!