SSAC iOS 앱 개발자 데뷔과정 - 14


🎛 Collection View

UICollectionView 는 여러 데이터를 커스텀 가능한 레이아웃을 사용해 사용자에게 보여줄 수 있는 객체입니다.

사용법이나 큰 틀은 앞서 공부한 Table View 와 크게 다르지 않습니다. 이번에도 역시 View Controller 위에 Collection View 를 추가하는 방식을 통해서 Collection View 를 구현해보겠습니다.


1 ) Collection View Cell 만들기

지난시간에 XIB 파일 형식으로 Table View Cell 을 만든것과 동일하게 Collection View Cell 을 만듭니다.

저번에 XIB 형태로 cell 을 만들면 해당 cell 을 중복해서 사용하기에 용이하다고 설명했었는데 Xib 파일과 Nib 의 차이점을 설명하지 않아서 간단하게 짚고 넘어가겠습니다.

  • xib : Xml Interface Builder
  • nib : Next Interface Builder

이 둘의 기능은 동일합니다. 실제로 xib 파일을 컴파일하게 되면 바이너리 형식으로 변형되어 nib 파일이 됩니다.

그럼, 우리는 왜 굳이 xib 파일을 사용할까요?

❗️nib 파일이 바이너리 형식이기 때문에 사람이 읽고 이해할 수 있는 형태가 아니기 때문입니다.

사람이 코드를 보고 이해할 수 없기 때문에 버전관리에도 어려움이 있기 때문에 사람이 보고 이해할 수 있는 xib 파일과 함께 사용합니다.

그럼 xib 파일로 우리가 사용할 cell 을 만들고 사용할 때는 nib 형태로 바꿔서 등록하던 과정이 왜 필요했던 것인지 이해 할수 있습니다!!

❗️ identifier 설정 잊지말기!!


2 ) Collection View 추가

Collection View 를 구성할 cell 의 디자인을 마쳤으니 ViewControllerCollection View 를 추가하는 과정이 필요합니다.

우리는 Collection ViewController 가 아닌 일반적인 View Controller 에서 Collection View 를 사용하기 때문에

CollectionViewDelegate, CollectionViewDataSource 프로토콜을 채택하는 과정이 필요합니다.

이와 같은 패턴을 Delegate Pattern 이라고 합니다.

extension StudyCollectionViewController: 
UICollectionViewDelegate, UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            
}

우선, 위와 같이 현재 ViewController 의 클래스 파일에 extension 을 이용해 사용할 프로토콜들을 추가해줍니다.
(ViewController 라는 알바생이 할 일들을 정리)

class StudyCollectionViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.delegate = self
        collectionView.dataSource = self
        let nibNmae = UINib(nibName: "StudyCollectionViewCell                            ", bundle: nil)
        collectionView.register(nibNmae, forCellWithReuseIdentifier: StudyCollectionViewCell.identifier)
        
    }
}

그리고 위임자를 정해주는 과정이 필요합니다.
collectionView 라는 사장이 StudyCollectionViewController(self) 가 알바생임을 선언

Delegate Pattern 에 대해서 더 알게되면 자세하게 따로 정리하겠습니다.

3 ) Collection View Layout 설정

UICollectionView FlowLayout 을 사용하면, 컬렉션 뷰의 셀을 원하는 형태로 정렬할 수 있습니다.

TableView 에서는 cell 을 설정하면서, 해당 cell 이 어떻게 나올지 설정했었는데(높이) Collection View 는 FlowLayout 클래스를 통해서 설정합니다.

부스토코스 이미지를 사용했습니다!

블로그1
블로그2

를 통해서, FlowLayout의 다양한 프로퍼티들을 확인 할 수 있습니다.


🏷 P.S.

어제 custom cell 내부에 존재하는 버튼을 통해서 어떤 동작을 구현하려고 하는걸 실패했었는데 오늘 수업시간에 배운 addTargettag 를 이용해서 성공했습니다!!

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell", for: indexPath) as? MainTableViewCell else {
            return UITableViewCell()
        }
        
        let row = tvShowInformation.tvShow[indexPath.row]
        
        cell.totalView.clipsToBounds = true
        cell.totalView.layer.cornerRadius = 10
        
        cell.genreLabel.text = row.genre
        cell.releaseDayLabel.text = row.releaseDate
        cell.titileLabel.text = row.title
        
        cell.rateLabel2.text = " \(row.rate) "
        
        cell.overViewLabel.numberOfLines = 1
        cell.overViewLabel.text = row.starring
        
        let url = URL(string: row.backdropImage)
        let data = try? Data(contentsOf: url!)
        cell.posterImageView.image = UIImage(data: data!)
        
        cell.detailButton.tag = indexPath.row
        cell.detailButton.addTarget(self, action: #selector(detailButtonClicked(selectButton:)), for: .touchUpInside)
        
        return cell
        
    }
@objc
    func detailButtonClicked(selectButton: UIButton) {
        
        let sb = UIStoryboard(name: "Main", bundle: nil)
        let vc = sb.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
        
        print(tvShowInformation.tvShow[selectButton.tag].title)

//이렇게 바로 넣으면 오류 
	//vc.titleLabel?.text = tvShowInformation.tvShow[selectButton.tag].title
    
        vc.movieLable = tvShowInformation.tvShow[selectButton.tag].title
        
        present(vc, animated: true, completion: nil)
        
    }

까먹기전에 코드를 한 번 정리하겠습니다.
우선, 우리가 디자인한 커스템 셀에 존재하는 어떤 버튼을 눌렀을 때, 화면전환 (show) 이 되고, 전환된 화면의 Label 을 해당 셀의 정보를 넘겨주는 것이 목표 입니다.

각 셀마다 다른 정보가 존재하는데 그런 정보를 화면전환 된 Label 에 표시해야 하기 때문에, 각 cellindexPath 정보가 필요합니다.

하지만 cell 클래스 파일, viewcontroller 클래스 파일에서 indexPath 정보를 사용할 수 없습니다.

이때, tag 를 사용합니다!

cell.detailButton.tag = indexPath.row

해당 코드를 통해서 tableview 에서 각 cell 을 만들때, cell 의 버튼에 해당 cell 의 indexPath.rowtag 로 저장합니다!

그리고 addTarget 을 통해서 각 셀의 버튼을 눌렀을 때, 어떤 동작을 할지 함수로 설정합니다.

해당 함수를 detailButtonClicked 라는 이름의 함수로 설정했습니다. 이는 어제 공부한 passData 와 동일합니다.

  • 그냥 바로 전환될 화면의 Label 에 값을 넣도록 설정하면 오류
  • 해당함수를 사용할 때 전달인자가 없어도 버튼에서 메서드를 호출해서 자동으로 설정됩니다.

컬렉션뷰나 테이블뷰는 개념 공부만이 아니라 절대적으로 제가 원하는 화면을 만들어 보는 과정이 필요한것 같습니다.

앞으로, 더 많이 만들어보면서 추가적으로 계속해서 정리할 수 있도록 하겠습니다!

좋은 웹페이지 즐겨찾기