본문 바로가기
🍎 iOS

[Swift] UIViewController 에 UICollectionView 넣기

by 틴디 2020. 9. 28.
728x90
반응형

안내

  해당 튜토리얼은 스토리보드에서 UICollectionViewController 로 시작하는 것이 아닌 UIViewController에 UIView를 넣고 해당 부분에 UICollectionView를 넣어주는 방법에 대한 내용입니다. 스토리 보드에서 UICollectionViewController로 시작하고자 하시면 다른 글을 참고해 주세요.

 

준비

프로젝트를 생성해 주고 빌드 해줍니다. 

스토리보드로 실행 되는 걸 확인할 수 있습니다. 

이제 스토리보드로 가서 UIView를 추가해 주겠습니다.

 

command + shift + L

 

원하는 영역에 맞추어 constraints를 추가해 줍니다.

 

이제 ViewController.swift를 열어 줍니다.

UICollectionView를 구현하기 위해서 UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout을

따르게 해야 합니다. 

 

에러가 난 이유는 꼭 구현해 줘야 하는 콜백 메소드를 구현하지 않아서 입니다. 

진행하며 구현해 주면 되니 우선 UICollectionView 프로퍼티를 작성하겠습니다.

 

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    
    let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.minimumLineSpacing = 0
        
        layout.scrollDirection = .vertical
        layout.sectionInset = .zero
        
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .green
        
        return cv
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        
    }


}

이렇게 프로퍼티를 작성하시면 collectionView를 사용할 시점에 코드 블럭 안에 있는 코드가 실행되면서 UICollectionView 타입의

collectionView를 생성합니다.

 

이때 초기화에 사용되는 layout을 커스텀 해줄 수 있는데

해당 방법은 차후에 포스팅 하겠습니다 ٩(*•̀ᴗ•́*)و 

 

 

아까 인터페이스 빌더에서 만들어둔 view를 스위프트 파일에 IBOulet으로 연결해 줍니다.

 

viewDidLoad()에서 인터페이스 빌더에서 만들어 준 뷰에 코드로 생성한 collectionView를 넣어주는 코드를 작성합니다

override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionView.delegate = self
        collectionView.dataSource = self
        
        verticalCollectionView.addSubview(collectionView)
        collectionView.frame = CGRect(x: 0, y: 0, width: self.verticalCollectionView.frame.width, height: self.verticalCollectionView.frame.height)
 }

이대로 실행하면 빌드 되지 않습니다

구현해 줘야 하는 메소드를 구현하지 않았기 때문입니다. 이제 필수로 구현해야 하는 메소드를 작성해 주겠습니다

에러 눌러서 fix 누르면 자동적으로 메소드가 작성됩니다

두 메소드를 작성하고

numberOfItemInSection은 섹션에 몇개의 셀이 들어가는 지 리턴해 줘야 하며

cellForItemAt 은 셀을 지정해 주는 메소드 입니다

셀은 재사용을 위해서 위와 같이 적어 줍니다.

기본적인 내용을 적어주고

이제 셀의 identifier를 등록해 줍니다.

viewDidLoad() 에 위와 같이 적어줍니다

 

빌드하고 실행해주면

이건 green이 아니라 형광 연두 아닌가..

지정해 준 뷰에  collectionView가 들어간 것을 확인할 수 있습니다

 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        50
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        
        for subview in cell.subviews {
            subview.removeFromSuperview()
        }
        
        let lbl: UILabel = {
            let lblTxt = UILabel()
            lblTxt.text = "\(indexPath.row)"
            lblTxt.textAlignment = .center
            return lblTxt
        }()
        
        cell.addSubview(lbl)
        lbl.frame = CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height)
        
        return cell
    }

cell은 임의로 50개로 만들어 줍니다

각 셀을 확인 하기 위해 cell에 indexPath의 row를 출력해 줄UILable을 추가했습니다

셀을 사용할 때는 재사용에 주의해야 합니다.

초기화나 셀에 뷰를 add 해주는 코드가 있다면 재사용 될때마다 뷰를 추가하기 때문에

이를 제거해주는 코드를 넣어 주었습니다

 

빌드하고 실행하면

이렇게 나와야 합니다

그런데 frame 지정할 때 이슈가 있네요

인터페이스 빌더에서 지정해준 뷰의 높이와 넓이를 그대로 가지고 와서 추가해 준 뷰가 짤려 보입니다

 

우선은 

    override func viewDidLoad() {
        super.viewDidLoad()
        
        verticalCollectionView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.verticalCollectionView.frame.height)
        
        self.collectionView.delegate = self
        self.collectionView.dataSource = self
        
        self.verticalCollectionView.addSubview(self.collectionView)
        self.collectionView.frame = CGRect(x: 0, y: 0, width: self.verticalCollectionView.frame.width, height: self.verticalCollectionView.frame.height)
        
        self.collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        
    }

이렇게 고쳐주고 

다음 포스팅에서 코드로 Anchor를 이용해서 컨트롤 뷰에 넣어주겠습니다!

 

틀리거나 이상한 점이 있다면 댓글로 알려주세요! 정말 감사합니다!

728x90
반응형

댓글