셀 간격과 UICollectionView를 설정하는 방법-UICollectionViewFlowLayout 크기 비율?


137

나는 추가하려고 해요 UICollectionViewViewController, 나는 (이 격자과 같아야합니다) 세포 사이의 빈 공간없이 '한 줄에'3 개 세포가 필요합니다. 셀 너비는 화면 크기의 1/3이어야하므로 너비가 같아야한다고 생각했습니다 layout.item. 그러나 나는 이것을 얻는다 :

layout.itemSize 너비 = screenSize.width / 3

그 크기를 줄이면 ( 예 : 7 또는 8 픽셀 ) 더 낫지 만 행의 세 번째 셀은 완전히 보이지 않으며 여전히 빈 공간이 있습니다 (상단 및 하단 및 왼쪽 및 오른쪽).

여기에 이미지 설명을 입력하십시오

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    var collectionView: UICollectionView?
    var screenSize: CGRect!
    var screenWidth: CGFloat!
    var screenHeight: CGFloat!

    override func viewDidLoad() {
        super.viewDidLoad()

        screenSize = UIScreen.mainScreen().bounds
        screenWidth = screenSize.width
        screenHeight = screenSize.height

        // Do any additional setup after loading the view, typically from a nib
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
        layout.itemSize = CGSize(width: screenWidth / 3, height: screenWidth / 3)
        collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        collectionView!.dataSource = self
        collectionView!.delegate = self
        collectionView!.registerClass(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
        collectionView!.backgroundColor = UIColor.greenColor()
        self.view.addSubview(collectionView!)
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as CollectionViewCell
        cell.backgroundColor = UIColor.whiteColor()
        cell.layer.borderColor = UIColor.blackColor().CGColor
        cell.layer.borderWidth = 0.5
        cell.frame.size.width = screenWidth / 3
        cell.frame.size.height = screenWidth / 3

        cell.textLabel?.text = "\(indexPath.section):\(indexPath.row)"
        return cell
    }
}

여기 당신의 해결책이 있습니다. 감사.
janu kansagra

여기에 작업 코드 스위프트 4입니다 stackoverflow.com/a/54703798/10150796
Nikunj Kumbhani

답변:


299

이 두 줄을 추가

layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0

그래서 당신은 :

   // Do any additional setup after loading the view, typically from a nib.
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
        layout.itemSize = CGSize(width: screenWidth/3, height: screenWidth/3)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        collectionView!.collectionViewLayout = layout

그러면 모든 공백이 제거되고 그리드 레이아웃이 제공됩니다.

여기에 이미지 설명을 입력하십시오

첫 번째 열의 너비를 화면 너비와 같게하려면 다음 함수를 추가하십시오.

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    if indexPath.row == 0
    {
        return CGSize(width: screenWidth, height: screenWidth/3)
    }
    return CGSize(width: screenWidth/3, height: screenWidth/3);

}

그리드 레이아웃은 다음과 같습니다 (첫 번째 셀에 파란색 배경을 추가했습니다). 여기에 이미지 설명을 입력하십시오


정말 고마워요. 좀 더 복잡한 것을 기대하고 있었고 많은 시간을 보냈습니다. 한 번 더 감사합니다.
Marko

그리고 한 가지 더, 첫 번째 셀에 대해서만 layout.itemSize 를 변경할 가능성이 있습니까? ( indexPath.row 가 0 일 때 cell.frame.size를 변경해야 하지만 한 항목에 대해서만 레이아웃 크기를 변경하는 방법을 모릅니다) 첫 번째 요소 너비는 screenWidth와 같아야 합니다 .
Marko

1
안녕하세요, 같은 문제가 있지만 Objective C의 비슷한 함수 제목을 알고 싶습니다.
Nada Gamal

1
좋아, 그것은 지금 잘 작동합니다, 고마워요 :) Objective C 함수 :-(CGSize) collectionView : (UICollectionView ) collectionView 레이아웃 : (UICollectionViewLayout ) collectionViewLayout sizeForItemAtIndexPath : (NSIndexPath *) indexPath {return CGSizeMake (screenWidth / 3, screenWidth / 3 ); }
Nada Gamal

4
@greentor의 훌륭한 답변에 감사드립니다. 현상금을 보냈습니다. collectionView를 잊지 마십시오 ! .collectionViewLayout = layout , 독자
Fattie

47

Swift 3 및 XCode 8의 경우 작동했습니다. 이것을 달성하려면 아래 단계를 따르십시오.

{
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    let width = UIScreen.main.bounds.width
    layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    layout.itemSize = CGSize(width: width / 2, height: width / 2)
    layout.minimumInteritemSpacing = 0
    layout.minimumLineSpacing = 0
    collectionView!.collectionViewLayout = layout
}

이 코드를 viewDidLoad () 함수에 넣습니다.


32

특정 상황에서는 UICollectionViewFlowLayoutin을 설정 viewDidLoad하거나 ViewWillAppearcollectionView에 영향을 미치지 않을 수 있습니다.

UICollectionViewFlowLayoutin을 설정하면 viewDidAppear런타임에 셀 크기가 변경되는 것을 볼 수 있습니다.

스위프트 3의 또 다른 해결책 :

extension YourViewController : UICollectionViewDelegateFlowLayout{

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let collectionViewWidth = collectionView.bounds.width
        return CGSize(width: collectionViewWidth/3, height: collectionViewWidth/3)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 20
    }
}

좋은 답변입니다! 이것은 분명히 Apple의 방법입니다. 이제 장치 방향이 바뀌면 새로 고치는 방법을 모르고 있습니까?
jlstr

17

Swift 3를 찾고 있다면 다음 단계를 수행하십시오.

func viewDidLoad() {

    //Define Layout here
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()

    //Get device width
    let width = UIScreen.main.bounds.width

    //set section inset as per your requirement.
    layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)

    //set cell item size here 
    layout.itemSize = CGSize(width: width / 2, height: width / 2)

    //set Minimum spacing between 2 items
    layout.minimumInteritemSpacing = 0

    //set minimum vertical line spacing here between two lines in collectionview
    layout.minimumLineSpacing = 0

    //apply defined layout to collectionview
    collectionView!.collectionViewLayout = layout

}

이것은 Swift 3이 설치된 Xcode 8.0에서 확인되었습니다.


8
let layout = myCollectionView.collectionViewLayout as? UICollectionViewFlowLayout
layout?.minimumLineSpacing = 8

4

스위프트 4

let collectionViewLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
collectionViewLayout?.sectionInset = UIEdgeInsetsMake(0, 20, 0, 40) 
collectionViewLayout?.invalidateLayout()

1

Swift 3 및 XCode 8의 경우 작동했습니다. 이것을 달성하려면 아래 단계를 따르십시오.

viewDidLoad()
    {
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        var width = UIScreen.main.bounds.width
        layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    width = width - 10
    layout.itemSize = CGSize(width: width / 2, height: width / 2)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        collectionView!.collectionViewLayout = layout
    }

3
여러 섹션이있는 경우 사실을 고려하는 방법
Nikhil Pandey

그것은 1 열 (섹션)에
대해서만

0

Swift 3+ 및 Xcode 9+의 경우 이것을 사용해보십시오

extension ViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    let collectionWidth = collectionView.bounds.width
    return CGSize(width: collectionWidth/3, height: collectionWidth/3)

}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 0

}

0

Swift 5 : 컨테이너 공간을 최대한 활용하기 위해 동적 셀 너비를 가진 셀 사이에 균등하게 분배 된 공간의 경우 minimumCellWidth 값 을 제공하여 아래의 코드 스 니펫을 사용할 수 있습니다 .

private func collectionViewLayout() -> UICollectionViewLayout {
    
    let layout = UICollectionViewFlowLayout()
    layout.sectionHeadersPinToVisibleBounds = true
    // Important: if direction is horizontal use minimumItemSpacing instead. 
    layout.scrollDirection = .vertical
    
    let itemHeight: CGFloat = 240
    let minCellWidth :CGFloat = 130.0
    let minItemSpacing: CGFloat = 10
    let containerWidth: CGFloat = self.view.bounds.width
    let maxCellCountPerRow: CGFloat =  floor((containerWidth - minItemSpacing) / (minCellWidth+minItemSpacing ))
    
    let itemWidth: CGFloat = floor( ((containerWidth - (2 * minItemSpacing) - (maxCellCountPerRow-1) * minItemSpacing) / maxCellCountPerRow  ) )
    // Calculate the remaining space after substracting calculating cellWidth (Divide by 2 because of left and right insets)
    let inset = max(minItemSpacing, floor( (containerWidth - (maxCellCountPerRow*itemWidth) - (maxCellCountPerRow-1)*minItemSpacing) / 2 ) )

    
    layout.itemSize = CGSize(width: itemWidth, height: itemHeight)
    layout.minimumInteritemSpacing = min(minItemSpacing,inset)
    layout.minimumLineSpacing = minItemSpacing
    layout.sectionInset = UIEdgeInsets(top: minItemSpacing, left: inset, bottom: minItemSpacing, right: inset)

    
    return layout
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.