简体   繁体   中英

swift: CollectionView cell size

I have collectionView with constraint to superview. I want to get this result for iPhone X:

在此输入图像描述

But I get this:

在此输入图像描述

How to fix it?

code:

func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 4
    }

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

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


        cellOffset = 10

        cellWidth = (667 / 3)  - (cellOffset * 4)
        cellHeight =  (cellWidth / 2 * 3) + (cellWidth / 2 * 0.65)

        return CGSize(width: cellWidth, height: cellHeight)
    }

Update

在此输入图像描述

Update

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

        let sectionInset = collectionView.frame.width / 3.0
        let margins = CGFloat(10.0 * 2.0)
        let width = (collectionView.frame.width - sectionInset - margins) / 3.0
        let height = collectionView.frame.height - 40.0

        let collectionViewLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
        collectionViewLayout?.sectionInset = UIEdgeInsets(top: 0, left: 6.0, bottom: 0, right: 6.0)
        collectionViewLayout?.minimumInteritemSpacing = 10
        collectionViewLayout?.invalidateLayout()

        return CGSize(width: width, height: height)
    }

result:

在此输入图像描述

如果你想在景观中有3个细胞

let cellWidth = ( self.collectionView.frame.width - 2 * cellOffset ) / 3
 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {



    return CGSize(width: collectionView.frame.size.width/4 - 1, height: collectionView.frame.size.width/4 - 1)
}

My suggestion would be to consider refactoring your layout a tad such that each section is inset on the left and right by the margin you're looking for. You could then describe your cell size in the following manner:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let sectionInset = collectionView.frame.width / 3.0
    let margins = CGFloat(10.0 * 2.0)
    let width = (collectionView.frame.width - sectionInset - margins) / 3.0
    let height = collectionView.frame.height - 40.0

    return CGSize(width: width, height: height)
}

Next you'd want to return this section inset value in the appropriate delegate method. Let's assume you want to reserve the first and last sixth of the collection view for this margin, which is roughly what your image shows.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0,
                        left: collectionView.frame.width / 6.0,
                        bottom: 0,
                        right: collectionView.frame.width / 6.0)
}

Putting it all together, we end up with this revision:

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 4
}

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

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let sectionInset = collectionView.frame.width / 3.0
    let margins = CGFloat(10.0 * 2.0)
    let width = (collectionView.frame.width - sectionInset - margins) / 3.0
    let height = collectionView.frame.height - 40.0

    return CGSize(width: width, height: height)
}

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

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0,
                        left: collectionView.frame.width / 6.0,
                        bottom: 0,
                        right: collectionView.frame.width / 6.0)
}

You need to set layout of collection view by this one.

// setup collection view
let numberItemPerRow = 4
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 0)
layout.itemSize = CGSize(width: ScreenSize.width/numberItemPerRow-1, 
                         height: ScreenSize.width/numberItemPerRow)
layout.minimumInteritemSpacing = 1
layout.minimumLineSpacing = 1
your_collection.collectionViewLayout = layout

I guarantee that this code will be solved. !!

You are making it a bit too complicated. It's just about playing a bit with the insets and the size. Here is the example code:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsetsMake(0, 145, 0, 145)
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 4
}

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    indePath = indexPath
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: self.view.frame.width / 3 - 100 , height: collectionView.frame.size.height - 100)
}

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

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

Here is the image of what it gives:

在此输入图像描述

Update

import UIKit

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate {

    lazy var collectionView : UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .green
        cv.isPagingEnabled = true
        cv.delegate = self
        cv.dataSource = self
        return cv
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(collectionView)
        collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
        collectionView.frame = self.view.frame
        collectionView.contentInset = UIEdgeInsetsMake(0, -45, 0, -45)
    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsetsMake(0, 145, 0, 145)
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 4
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: self.view.frame.width / 3 - 100 , height: collectionView.frame.size.height - 100)
    }

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

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

}

class Cell : UICollectionViewCell {


    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupViews() {
        self.backgroundColor = .red
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM