Weird error returning CGSize in UICollectionView sizeForItemAtIndexPath

I have a variable width in my UICollectionView and in my function sizeForItemAtIndexPath, I end up returningCGSize

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

    var width: CGFloat = indexPath.row == 0 ? 37 : 20 // default paddings based on spacing in cell
    let font = UIFont.systemFont(ofSize: 14, weight: UIFontWeightRegular)

    if indexPath.row == 0 {
        width += listingsFilter.stringValue.width(withConstrainedHeight: 28, font: font)
    } else {
        let string = viewModel.valueRangeForButton[indexPath.row - 1]
        width += string.width(withConstrainedHeight: 28, font: font)
    }

    print(width) // some decimal e.g. 138.1239581
    let w: CGFloat = width.rounded() // rounded e.g. 13

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

If I close the return value with a number for the width, say 128, and not with a variable, the collection view will look UIEdgeInsets. If I return CGSizewith a variable for the width, it UIEdgeInsetswill be ignored for each element, but the first and last.

I feel like I discovered some deep mistake CoreGraphics.

For the last two lines, if I change them to

let x: CGFloat = 128 // or 128.0, doesn't matter
return CGSize(width: x, height: 28)

It still does not work. I tried to return CGSizewith an initializer Int. I tried casting for Ints and returned to CGFloats. Nothing seems to work.

. width ( ) - .

. - ?

:

CGSize(width: w, height: 28), w CGFloat, 128 . CGSize(width: 128, height: 28)

enter image description here

enter image description here

+4
5

. , , ( ), .
, UICollectionViewDelegateFlowLayout. UICollectionViewDelegate. .
, .

0

op

,

func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout:
    UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

    return UIEdgeInsets(top: 15, left: 0, bottom: 15, right: 0)
}

,

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

, UICollectionViewDelegateFlowLayout

0

sizeForItemAtIndexPath(), , UIEdgeInsets UICollectionView, , . , UIEdgeInsets , , Apple , , - UIEdgeInsets , . , UIEdgeInsets, UICollectionView. . , .

, UICollectionViews, , , , :

UICollectionView, , " " " " , ( 10). " " - . "For Lines", .

0

, ,

class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    collectionView?.delegate = self
    collectionView?.contentInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}



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

    let x: CGFloat = 50 + CGFloat(arc4random_uniform(50)) // or 128.0, doesn't matter
    return CGSize(width: x, height: 28)
}

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

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


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


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


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

}

enter image description here

0

It is not related to UIEdgeInsets, it refers to widthwhich you compute in code. When you set width: 128, the width provided for your cells is greater than what they really need (say 90), so depending on your design UICollectionViewCell, it may feel like there is UIEdgeInsetsfor each cell.

To solve your problem:

If you use the IB, you can set cellSpacingand lineSpacingfrom the IB, or you will have to implementUICollectionViewDelegateFlowLayout

-1
source

Source: https://habr.com/ru/post/1674342/


All Articles