2

我一直在使用自定义UICollectionViewFlowLayout来调整单元格之间的空间,这样我就可以在我的collectionView. 但是使用我当前的代码,我无法弄清楚如何在不“破坏”行数的情况下调整单元格大小。这使得一些单元格认为它们可以容纳一行,但它们不能。

我的自定义流程布局

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
    }
}

所以在我的ViewController我已经扩展

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
    }
}

当我尝试这段代码时,我在 iPhone X 的结果部分中得到了结果。您可以看到标签“机器学习”跳到新行,因为它认为它可以适合上面的行。如果我删除函数中单元格的“填充” sizeForItem,那么我就不会有这个问题。但它看起来很糟糕。

所以我的问题是:如何在不破坏 flowLayout 的情况下在单元格上使用填充?


到目前为止,我目前的结果如下所示:

iPhone X:

iPhone X 结果

4

2 回答 2

3

也许它会帮助你。我认为你应该检查你的项目是否突出了集合视图的右插图。在layoutAttributesForElements方法中检查这个:

        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 
        }

更新了我的答案,它对我有用,你可以在截图上看到

于 2018-10-03T14:14:17.183 回答
0

我也在实现标签布局。我尝试使用以下方法,但它不适合我。

我该如何纠正这个?

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            guard let attributesForElementsInRect = super.layoutAttributesForElements(in: rect) else { return nil }
            guard var newAttributesForElementsInRect = NSArray(array: attributesForElementsInRect, copyItems: true) as? [UICollectionViewLayoutAttributes] else { return nil }
            
            var leftMargin: CGFloat = 0.0;
            let collectionViewWidth = self.collectionView?.frame.width ?? 0 - (self.sectionInset.right + self.sectionInset.left)
            for attributes in attributesForElementsInRect {
                if (attributes.frame.origin.x == self.sectionInset.left) {
                    leftMargin = self.sectionInset.left
                }
                else if (attributes.frame.origin.x + attributes.frame.size.width > collectionViewWidth) {
                    var newLeftAlignedFrame = attributes.frame
                    newLeftAlignedFrame.origin.x = self.sectionInset.left
                    attributes.frame = newLeftAlignedFrame
                 }
                
                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
        }
于 2022-01-07T07:34:17.810 回答