UICollectionView - 删除额外的间距

时间:2017-11-26 10:44:35

标签: ios objective-c uicollectionview uicollectionviewcell uicollectionviewlayout

我有一个iPad应用程序用于UICollectionView来显示单元格网格。细胞具有完全相同的宽度但不同的高度(因为一些细胞具有比其他细胞更多的文本)。

我遇到的唯一问题是较短的单元格,最终在上方/下方有额外的间距....这会产生一个看起来很糟糕的集合视图。它增加了额外的空间,不需要额外的空间。我试图将边缘插入设置为0,将最小行间距设置为0,但它仍然不能正常工作。

以下是我的集合视图:

enter image description here

这就是我想要的样子:

enter image description here

这是我的流程布局代码:

[self.infoList registerClass:[InfoCell class] forCellWithReuseIdentifier:@"InfoCell"];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
[layout setItemSize:CGSizeMake(320, 160)];
[layout setScrollDirection:UICollectionViewScrollDirectionVertical];
[layout setMinimumInteritemSpacing:0];
[layout setMinimumLineSpacing:0];
[self.infoList setCollectionViewLayout:layout];

我也将边缘插入设置为0:

-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsZero;
}

如何删除多余的空间?我找到的唯一方法就是让所有的细胞都完全相同......但是我想要的东西。有些单元格包含文本而不是其他单元格,所以我必须给它们额外的高度。

谢谢你的时间,Dan。

1 个答案:

答案 0 :(得分:2)

在我看来,您可以通过自定义UICollectionViewLayout解决此问题。你应该看一下https://snoopwpf.codeplex.com/

使用下面的代码,我假设每行有2行列,项目具有相同的宽度和不同的高度。

const CGFloat kPadding                         = 5.f;
const NSUInteger kNumberSmallCellALine         = 2;

@interface CustomCollectionViewLayout : UICollectionViewLayout

@property (nonatomic, strong) NSMutableArray *layoutAttributes;
@property (nonatomic, assign) CGFloat contentHeight;

@end

@implementation CustomCollectionViewLayout

// Use this method to perform the up-front calculations needed to provide layout information.
- (void)prepareLayout{
  [super prepareLayout];

  if (!self.layoutAttributes){
    self.layoutAttributes = [[NSMutableArray alloc] init];

    // Calculate width of each item
    CGFloat cellWidth = (self.collectionView.frame.size.width - (kNumberSmallCellALine - 1) * kPadding) / kNumberSmallCellALine;
    // Default height of contentSize
    self.contentHeight = 0.f;
    // Height of column items on the left
    CGFloat leftColumnHeight = 0.f;
    // Height of column items on the right
    CGFloat rightColumnHeight = 0.f;

    for (int i = 0 ; i < [self.collectionView numberOfItemsInSection:0] ; i ++){

      // Height of item at index i
      CGFloat height = i * 20 + 20;

      CGFloat xPos, yPos = 0.f;

      if (i % 2 == 0) {
        // If item on the right
        xPos = 0.f;
        yPos = leftColumnHeight;
        leftColumnHeight += height + kPadding;
      } else {
        // Item on the left
        xPos = cellWidth + kPadding;
        yPos = rightColumnHeight;
        rightColumnHeight += height + kPadding;
      }

      // Update height of contentSize after adding new item
      self.contentHeight = MAX(leftColumnHeight, rightColumnHeight);

      UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
      attr.frame = CGRectMake(xPos,
                              yPos,
                              cellWidth,
                              height);
      [self.layoutAttributes addObject:attr];
    }
  }
}

// Use this method to return the attributes for cells and views that are in the specified rectangle.
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
  NSMutableArray *currentAttributes = [NSMutableArray new];
  for (UICollectionViewLayoutAttributes *attr in self.layoutAttributes) {
    if (CGRectIntersectsRect(attr.frame, rect))
    {
      [currentAttributes addObject:attr];
    }
  }
  return currentAttributes;
}

// Use this method to return the overall size of the entire content area based on your initial calculations.
- (CGSize)collectionViewContentSize{
  return CGSizeMake(self.collectionView.frame.size.width, self.contentHeight);
}

@end

使用

CustomCollectionViewLayout *layout = [[CustomCollectionViewLayout alloc] init];
[collectionView setCollectionViewLayout:layout];

这是一个解决您的问题的演示。你应该改变每个项目的高度,以适合你的情况。

有关更多信息和更易于理解,请查看Collection View Programming Guide for iOS

来自@Supertecnoboff

注意

如果您支持多个设备方向(例如:iPad应用程序),则必须重新加载layoutAttributes数据。否则旋转设备时布局将不正确。然后,您需要在集合视图上调用performBatchUpdates以加载新的布局数据。