UICollectionView에서 넓은 정사각형의 셀을 쉽게 배열해 보세요.

10559 단어 XcodeSwiftiOS
기본 사진 응용 프로그램

문서 레지스트리에 항목 추가
itemSize를 계산하고 cell과 cell 사이에 간격이 있는 상황을 고려하여 sectionInset을 반영하고 싶다...이렇게 하면 매우 번거로울 것이다.
결정할 수 있지만 collectionView의 가로 너비는 Auto-Layout에서 변동하는 상황에서 그와 비교할 수 없다...
기본 화면은 가로로 collection View를 펼치고 Uiscreen에서 화면의 현수막을 받아서 계산하면 되잖아!그런 경우도 있지만 그렇지 않은 경우도 있으니 가능하면 피하고 싶다.
그래서 조금의 번거로운 일도 고려하지 않고 쉽게 extension을 썼다.

특징

  • 복잡한 컴퓨팅 불필요
  • 호출 처리 시 즉시 레이아웃 변경
  • sectionInset을 지정하지 않으면space에서 지정한 값을 inset의 모든 요소에 넣기 때문에 모든 간격이 고정됩니다.

  • collectionView의 scrollDirection이 Vertical이면 가로 너비를 등분하고, Horizontal이면 세로 너비를 등분합니다.
  • ※ 스페이스 값이 크거나perRow 값이 0 이하일 경우 레이아웃 처리를 하지 않습니다.
  • 실시


    이런 느낌이에요.
    extension
    import UIKit
    
    public extension UICollectionView {
    
        public func adaptBeautifulGrid(numberOfGridsPerRow: Int, gridLineSpace space: CGFloat) {
            let inset = UIEdgeInsets(
                top: space, left: space, bottom: space, right: space
            )
            adaptBeautifulGrid(numberOfGridsPerRow, gridLineSpace: space, sectionInset: inset)
        }
    
        public func adaptBeautifulGrid(numberOfGridsPerRow: Int, gridLineSpace space: CGFloat, sectionInset inset: UIEdgeInsets) {
            guard let layout = collectionViewLayout as? UICollectionViewFlowLayout else {
                return
            }
            guard numberOfGridsPerRow > 0 else {
                return
            }
            let isScrollDirectionVertical = layout.scrollDirection == .Vertical
            var length = isScrollDirectionVertical ? self.frame.width : self.frame.height
            length -= space * CGFloat(numberOfGridsPerRow - 1)
            length -= isScrollDirectionVertical ? (inset.left + inset.right) : (inset.top + inset.bottom)
            let side = length / CGFloat(numberOfGridsPerRow)
            guard side > 0.0 else {
                return
            }
            layout.itemSize = CGSize(width: side, height: side)
            layout.minimumLineSpacing = space
            layout.minimumInteritemSpacing = space
            layout.sectionInset = inset
            layout.invalidateLayout()
        }
    
    }
    

    시험적으로 사용하다


    전제 조건은collectionView에collectionViewFlowLayout이 추가되었습니다.
    업데이트를 하고 싶은 타이밍입니다.
    // 横に4等分した幅を持つcellでレイアウトする。間隔は2.0px空ける
    collectionView.adaptBeautifulGrid(4, gridLineSpace: 2.0)
    
    // 最初に貼った写真アプリとほぼ同様のレイアウトをする。
    // 横に4等分した幅を持つcellでレイアウトする。間隔は1.0px空ける
    // 更に、sectionInset(top,bottomが10px,left,rightが0.0px)を指定する。
    let inset = UIEdgeInsetsMake(10.0, 0.0, 10.0, 0.0)
    collectionView.adaptBeautifulGrid(4, gridLineSpace: 1.0, sectionInset: inset)
    
    
    이렇게 부르면 즉석에서 변경됩니다.
    stepper에서 지정한 값을 변경할 때 상기 과정을 호출하여 업데이트하는 것을 보여 줍니다.
    상황에 따라 viewDidLayoutSubviews()와viewDidAppear() 근처에 입고하면
    왜냐하면 collectionView의 프레임을 Auto-Layout이 정한 다음에 레이아웃을 설정할 수 있으니까요.
    4인치, 4.7인치, 5.5인치 모두 같은 레이아웃을 할 수 있다.
    회전 가능한 화면에서 세로 화면과 가로 화면을 통해 격자 수를 바꾸고 싶다면
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        view.layoutIfNeeded()
        let isLandscape = UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation)
        let perRow = 4 + (isLandscape ? 2 : 0)
        collectionView.adaptBeautifulGrid(perRow, gridLineSpace: 2.0)
    }
    
    이렇게 쓰면 회전할 때 격자 수를 종횡으로 바꿀 수 있다.
    느낌이 비슷해요. 5.5인치일 때만 격자 수를 하나 늘릴 수 있을 것 같아요.

    마지막


    소스 코드와 프레젠테이션은 여기 위에 있습니다.일시적으로carthage를 지원하기 때문에 라이브러리로 가져올 수 있습니다.

    좋은 웹페이지 즐겨찾기