我如何在UICollectionView的一个部分设置单元格间距?我知道有一个属性minimumInteritemSpacing,我已经将它设置为5.0,但间距仍然没有出现5.0。我已经实现了flowout委托方法。

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{

    return 5.0;
}

我仍然没有得到想要的结果。我认为这是最小间距。有没有什么方法可以设置最大间距?


当前回答

以前的版本并没有真正工作的部分> 1。所以我的解决方案在这里找到了https://codentrick.com/create-a-tag-flow-layout-with-uicollectionview/。对于懒惰的人:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
    var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
    // use a value to keep track of left margin
    var leftMargin: CGFloat = 0.0;
    for attributes in attributesForElementsInRect! {
        let refAttributes = attributes 
        // assign value if next row
        if (refAttributes.frame.origin.x == self.sectionInset.left) {
            leftMargin = self.sectionInset.left
        } else {
            // set x position of attributes to current margin
            var newLeftAlignedFrame = refAttributes.frame
            newLeftAlignedFrame.origin.x = leftMargin
            refAttributes.frame = newLeftAlignedFrame
        }
        // calculate new value for current margin
        leftMargin += refAttributes.frame.size.width + 10
        newAttributesForElementsInRect.append(refAttributes)
    }

    return newAttributesForElementsInRect
}

其他回答

试试下面的代码,确保每个项目之间的间距为5px:

- (UIEdgeInsets)collectionView:(UICollectionView *) collectionView 
                        layout:(UICollectionViewLayout *) collectionViewLayout 
        insetForSectionAtIndex:(NSInteger) section {

    return UIEdgeInsetsMake(0, 0, 0, 5); // top, left, bottom, right
}

- (CGFloat)collectionView:(UICollectionView *) collectionView
                   layout:(UICollectionViewLayout *) collectionViewLayout
  minimumInteritemSpacingForSectionAtIndex:(NSInteger) section {    
    return 5.0;
}

试试这个方法:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
                    layout:(UICollectionViewLayout*)collectionViewLayout
    insetForSectionAtIndex:(NSInteger)section {

    UIEdgeInsets insets = UIEdgeInsetsMake(?, ?, ?, ?);

    return insets;
}

上面vojtech-vrbka的解决方案是正确的,但它会触发一个警告:

警告:UICollectionViewFlowLayout缓存的帧不匹配索引路径-缓存值:这可能是因为流布局子类layout是修改UICollectionViewFlowLayout返回的属性而没有复制它们

下面的代码应该修复它:

class CustomViewFlowLayout : UICollectionViewFlowLayout {

   let cellSpacing:CGFloat = 4

   override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
       let original = super.layoutAttributesForElementsInRect(rect)

       if let original = original {
           let attributes = NSArray.init(array: original, copyItems: true) as! [UICollectionViewLayoutAttributes]

           for (index, attribute) in attributes.enumerate() {
                if index == 0 { continue }
                let prevLayoutAttributes = attributes[index - 1]
                let origin = CGRectGetMaxX(prevLayoutAttributes.frame)
                if(origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize().width) {
                    attribute.frame.origin.x = origin + cellSpacing
                }
            }
            return attributes
       }
       return nil
   }
}

我知道这个话题很老了,但如果有人还需要正确答案,你需要什么:

Override standard flow layout. Add implementation like that: - (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect { NSArray *answer = [super layoutAttributesForElementsInRect:rect]; for(int i = 1; i < [answer count]; ++i) { UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i]; UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1]; NSInteger maximumSpacing = 4; NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame); if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) { CGRect frame = currentLayoutAttributes.frame; frame.origin.x = origin + maximumSpacing; currentLayoutAttributes.frame = frame; } } return answer; }

其中maximumSpacing可以设置为您喜欢的任何值。这个技巧保证了单元格之间的空间将等于maximumSpacing!!

以前的版本并没有真正工作的部分> 1。所以我的解决方案在这里找到了https://codentrick.com/create-a-tag-flow-layout-with-uicollectionview/。对于懒惰的人:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
    var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
    // use a value to keep track of left margin
    var leftMargin: CGFloat = 0.0;
    for attributes in attributesForElementsInRect! {
        let refAttributes = attributes 
        // assign value if next row
        if (refAttributes.frame.origin.x == self.sectionInset.left) {
            leftMargin = self.sectionInset.left
        } else {
            // set x position of attributes to current margin
            var newLeftAlignedFrame = refAttributes.frame
            newLeftAlignedFrame.origin.x = leftMargin
            refAttributes.frame = newLeftAlignedFrame
        }
        // calculate new value for current margin
        leftMargin += refAttributes.frame.size.width + 10
        newAttributesForElementsInRect.append(refAttributes)
    }

    return newAttributesForElementsInRect
}