ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift] Compositional Layout - 레이아웃 그려보기
    개발/Swift 2022. 11. 22. 16:45

     

    Modern Collection View 와 MVVM 패턴 가이드

    다양한 사이즈 형태의 collection view를 구현 하기 위해 Group을 잘 짜줘야 한다.

    let group = NSCollectionLayoutGroup.vertical(
    	layoutSize: NSCollectionLayoutSize(
    widthDimension: .fractionalWidth(1.0),
     heightDimension: .fractionalWidth(16/9)),
     subitems: [다양한 그룹들])
    

    (각 그룹들의 높이는 고정값으로 지정했으니 무시)

    위 그룹의 subItems 안에 다양한 타입의 그룹이 들어갈것이고

    해당 그룹들은 vertical 하게 들어갈것이다.

     

    다음 예시를 통해 여러 타입의 collectionview 를 그려볼것이다.

     

    가장 먼저 1번 - 너비는 width * 1

    높이는 width * 2/3 크기를 가지고 있다.

    let fullItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/3)))
    //padding 추가
    fullItem.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
    

    해당 fullItem을 가지고 레이아웃을 리턴한다

    func generateLayout() -> UICollectionViewLayout {
    
        
        let fullItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/3)))
        fullItem.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
    
        
        let group = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(16/9)), subitems: [fullItem])
        let section = NSCollectionLayoutSection(group: group)
    
        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
      }
    

    그룹 안에 해당 fullitem을 너어주면 모든 아이템들이 fullItem 사이즈로 그려진다.

     

    2번 레이아웃

    2번 은 두가지 타입으로 나뉜다.

    왼쪽의 큰 메인이미지, 오른쪽의 서브이미지그룹

    이 두 타입을 그룹으로 묶어야한다. (2번 그룹이라 하자)

    2번 그룹의 너비는 width * 1 높이는 width * 4/9 로 지정해줬다.

    그리고 두 타입(메인이미지 + 서브그룹) 이미지는 horizontal로 정렬 된다. ( 좌 우로 그려지므로)

    let mainAndSubGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(4/9)), subitems: [MainItem, subGroup])
    

    이렇게 그룹을 만들것이다.

    구성은 이렇게 된다

    • 전체 그룹
      • 2번 그룹
        • 메인이미지
        • 서브이미지 그룹

    이제 들어갈 아이템을 그려본다.

    메인이미지는 width * 2/3

    높이 height * 1 (2번 그룹의 기준) 를 가진다.

    let mainItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(2/3), heightDimension: .fractionalHeight(1.0)))
    

    서브 이미지 그룹의 너비는 width * 1/3

    높이는 height * 1 일것이고 ( 2번 그룹 기준)

    위아래로 두개 들어갈 서브 이미지의 너비는 width * 1

    높이 height * 1/2 사이즈이다.

    let subItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1/2)))
    let subGroup = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1.0)), subitem: subItem, count: 2)
    

    이제 mainAndSubGroup 을 그룹에 넣어주면

     

     

    이렇게 fullItem, mainAndSubGroup 식으로 반복된다.

     

    4번 레이아웃

    4번은 2번을 반대로 하면 된다. 이미 구현했으니 순서만 바꾼 그룹을 만들면 된다.

    let subGroupAndMain = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(4/9)), subitems: [subGroup, mainItem])
    

    3번 레이아웃

    3번 - 너비 width * 1/3 인 아이템들을 그룹에 넣어주면된다.

    let trippleItme = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1.0)))
        let trippleGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/9)), subitem: trippleItme, count: 3)
    

    전체코드

    func generateLayout() -> UICollectionViewLayout {
        let contentInset = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
        
        let fullItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/3)))
        fullItem.contentInsets = contentInset
    
        
        let mainItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(2/3), heightDimension: .fractionalHeight(1.0)))
        mainItem.contentInsets = contentInset
        let subItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1/2)))
        subItem.contentInsets = contentInset
        let trippleItme = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1.0)))
        trippleItme.contentInsets = contentInset
    
        let trippleGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(2/9)), subitem: trippleItme, count: 3)
    
        let subGroup = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1/3), heightDimension: .fractionalHeight(1.0)), subitem: subItem, count: 2)
        
        let mainAndSubGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(4/9)), subitems: [mainItem, subGroup])
      
        let subGroupAndMain = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(4/9)), subitems: [subGroup, mainItem])
    
        let group = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(16/9)), subitems: [fullItem, mainAndSubGroup, trippleGroup, subGroupAndMain])
        let section = NSCollectionLayoutSection(group: group)
    
        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
      }
    

     

    참조 : https://www.kodeco.com/5436806-modern-collection-views-with-compositional-layouts

    댓글

Designed by Tistory.