I've been working on with a custom UICollectionViewFlowLayout
to adjust the spaces between the cells so I can get a nice flow in my collectionView
. But with my current code I can't figure out how I can adjust the cell sizes without "breaking" rows count. Which makes some cells think they can fit a row but they can't.
class UserProfileTagsFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
var leftMargin: CGFloat = 0.0;
for attributes in attributesForElementsInRect! {
if (attributes.frame.origin.x == self.sectionInset.left) {
leftMargin = self.sectionInset.left
} else {
var newLeftAlignedFrame = attributes.frame
newLeftAlignedFrame.origin.x = leftMargin
attributes.frame = newLeftAlignedFrame
}
leftMargin += attributes.frame.size.width + 8 // Makes the space between cells
newAttributesForElementsInRect.append(attributes)
}
return newAttributesForElementsInRect
}
}
So in my ViewController
I've extende
extension myViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let tag = tagsArray[indexPath.row]
let font = UIFont(name: "Raleway", size: 14)!
let size = tag.value.size(withAttributes: [NSAttributedString.Key.font: font])
let dynamicCellWidth = size.width
/*
The "+ 20" gives me the padding inside the cell
*/
return CGSize(width: dynamicCellWidth + 20, height: 35)
}
// Space between rows
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
// Space between cells
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
}
When I try this code out i'm getting the result down in the result-section on an iPhone X. You can see the tag "Machine Learning" jumps down to a new row, because it thinks it can fit the row above. If I remove the "padding" for the cell in sizeForItem
function, then I won't have this problem. But it just looks awful.
So my question is: How can I use padding on my cells without breaking the flowLayout?
iPhone X:
Maybe it will help you. I think you should check if you item stick out the collection view right inset.
In layoutAttributesForElements
method check this:
let collectionViewWidth = self.collectionView?.frame.width - (self.sectionInset.right + self.sectionInset.left)
if (attributes.frame.origin.x + attributes.frame.size.width > collectionViewWidth) {
var newLeftAlignedFrame = attributes.frame
newLeftAlignedFrame.origin.x = self.sectionInset.left
attributes.frame = newLeftAlignedFrame
}
Updated my answer and it works for me, you can see it on screenshot