[iOS] Flow Layout

RudinP·2024년 5월 7일
0

Study

목록 보기
227/258

cell의 크기를 설정할 때 분명 inspector에서 cell size를 설정했는데도 실제로는 적용이 되지 않아 난항을 겪은 적이 있을것이다. 이는 Estimate Size의 옵션을 Automatic으로 설정하였기 때문이다. 이 경우, cell은 주어진 제약에 맞춰 Self Sizing을 하게 된다.

Self Sizing

  • Inspector에서 설정하고 싶은 경우 Estimate Size의 옵션을 Automatic이 아닌, None으로 두어야 한다.
  • Estimate Size 옵션은 CollectionView와 TableView 모두 디폴트로 Automatic으로 설정되어있다.
  • 이 옵션 외에 크기를 설정하는 방법으로는 delegate 메소드로 크기를 직접 리턴하는 방법이 있다.

FlowLayout으로 Grid UI 구현하기

  • 컬렉션뷰는 셀을 표시할 때 레이아웃 객체를 사용하는데, 기본 레이아웃 이름이 Flow이다.
  • 이 레이아웃 자체도 델리게이트 패턴을 사용한다.

  • 특정 셀의 크기가 필요할 때 이 메소드를 호출한다.
  • 이 메소드를 구현하지 않으면 itemSize의 속성을 사용한다.
    • 어트리뷰트 인스펙터, 사이즈 인스펙터에서 설정한 속성
    • 이 메소드를 구현하면 위에서 설정한 속성은 무시된다.
    • 여기서 리턴하는 크기는 반드시 컬렉션 뷰의 너비, 높이를 초과해서는 안된다.
extension MainViewController: UICollectionViewDelegateFlowLayout{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        let width = collectionView.bounds.width / 2
        
        return CGSize(width: width, height: width)
    }
}

Min Spacing

  • 셀 사이의 여백을 설정할 수 있다.

  • 고정 값이 아니라, 최솟값이다. 즉, 어느 부분에서는 여백이 더 커질 수 있다.

  • For Cells: 셀 사이의 여백

  • For Lines: 줄 사이의 여백

  • 만약 한 줄에 두 개의 셀을 표시하고 싶어 여백값을 사용해야 할 땐, 여백의 고정값이 아니라 직접 변수로 접근해 값을 받아오는 것이 바람직하다. 이 값은 FlowLayout의 속성에 정의되어 있다.

UICollectionViewFlowLayout

  • scrollDirection: 콜렉션뷰의 스크롤 방향. 기본값은 vertical
  • minimumLineSpacing: 최소 라인 여백
  • minimumInteritemSpacing: 최소 셀 사이 여백
extension MainViewController: UICollectionViewDelegateFlowLayout{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout else { return .zero }
        
        //소수점때문에 뷰가 망가지는 경우 방지
        let width = Int((collectionView.bounds.width - flowLayout.minimumInteritemSpacing) / 2)
        
        return CGSize(width: width, height: width)
    }
}

만약, section별 inset도 추가했다면
flowLayout.minimumInteritemSpacing flowLayout.sectionInset.left
flowLayout.sectionInset.right
모두 고려해야 한다.

extension MainViewController: UICollectionViewDelegateFlowLayout{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout else { return .zero }
        
        //소수점때문에 뷰가 망가지는 경우 방지
        let width = Int((collectionView.bounds.width - (flowLayout.minimumInteritemSpacing + flowLayout.sectionInset.left + flowLayout.sectionInset.right)) / 2)
        
        return CGSize(width: width, height: width)
    }
}
profile
iOS 개발자가 되기 위한 스터디룸...

0개의 댓글