본문 바로가기

iOS/Toy project

[iOS : Toy Project] Apple Music App (4) : HeaderView (CollectionReusableView)

이전 포스팅

- AppleMusicApp(1) : 뷰 구성

- AppleMusicApp(2) : Track 모델 (데이터 구조)

- AppleMusicApp(3) : UICollectionView 업데이트

 

자세한 코드는 여기로!

https://github.com/yexjin/iOS_Study/tree/main/AppleMusicApp

 

GitHub - yexjin/iOS_Study: iOS 토이프로젝트 모음집📱

iOS 토이프로젝트 모음집📱. Contribute to yexjin/iOS_Study development by creating an account on GitHub.

github.com

 

 

 

 


9/13

- 이번엔 CollectionReusableView로 만들어뒀던 HeaderView를 마무리지어보겠다!

 

HeaderView에 띄울 내용은 TrackManager의 todayMusic 이다

1️⃣ todayMusic 가져오기

//  HomeViewController.swift
// 헤더뷰 표시
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    // kind: supplementary view 종류 (header or footer)
    switch kind {
    case UICollectionView.elementKindSectionHeader:
        guard let item = trackManager.todayMusic else {
            return UICollectionReusableView()
        }
        guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TrackCollectionHeaderView", for: indexPath)as? TrackCollectionHeaderView else {
            return UICollectionReusableView()
        }

        return header

    default:
        return UICollectionReusableView()
    }
}

 

 

2️⃣ headerView 업데이트 함수 (TrackCollectionHeaderView.swift에!)

// TrackCollectionHeaderView.swift
import UIKit
import AVFoundation

class TrackCollectionHeaderView: UICollectionReusableView {
    @IBOutlet weak var thumbnailImageView: UIImageView!
    @IBOutlet weak var discriptionLabel: UILabel!
    
    var item: AVPlayerItem?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        thumbnailImageView.layer.cornerRadius = 4
    }
    
    func update(with item: AVPlayerItem) {
        // TODO: 헤더뷰 업데이트
        
        self.item = item
        guard let track = item.convertToTrack() else { return }
        self.thumbnailImageView.image = track.artwork
        self.discriptionLabel.text = "Today's pic is \(track.artist)'s album - \(track.albumName), Let's listen."
    }
    
}

item을 받아와서 convertToTrack() 을 통해, AVPlayerItem을 Track 타입으로 Type Casting

 

 

 

3️⃣ 다시 HomeViewController에서 업데이트 함수 적용

// 헤더뷰 표시
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    // kind: supplementary view 종류 (header or footer)
    switch kind {
    case UICollectionView.elementKindSectionHeader:
        guard let item = trackManager.todayMusic else {
            return UICollectionReusableView()
        }
        guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TrackCollectionHeaderView", for: indexPath)as? TrackCollectionHeaderView else {
            return UICollectionReusableView()
        }

		// 업데이트
        header.update(with: item)

        return header

    default:
        return UICollectionReusableView()
    }
}

 

 

4️⃣ HeaderView의 플레이 button을 탭했을 경우, 이벤트 처리

IBAction 연결

 

연결 코드 작성

//  TrackCollectionHeaderView.swift

import UIKit
import AVFoundation

class TrackCollectionHeaderView: UICollectionReusableView {
// ...
    var tapHandler: ((AVPlayerItem) -> Void)?
    
    // ...
   
    @IBAction func cardTapped(_ sender: UIButton) {
        // TODO: 탭했을때 처리
        
        guard let todaysItem = item else { return }
        tapHandler?(todaysItem)
        
    }
    
}

tapHandler는 옵셔널 처리되어있어서 아무런 반응이 없다!

→ HomeViewController에서 이를 tapHandler가 작동되게끔 해야한다!

header.tapHandler = {item -> Void in
    // 아직 플레이어 화면 구현을 안했기 때문에 출력만 진행
    print("--> play \(item.convertToTrack()?.title)")
}

 

 

🚀 구현화면

 

빨간색 버튼을 눌렀을 경우,

출력도 잘되는 것을 확인할 수 있음!

 

 

 

 


저 빨간색 버튼을 눌렀을 경우, 플레이 화면으로 넘어가야하는데 아직 이부분은 View를 구성하지도 않았기 때문에 다음에 할일!