UICollectionView - ZhiJianShuSheng/Read-And-Learn GitHub Wiki

Layout Objects

使用UICollectionViewFlowLayout类进行具体的布局实现,类的官方文档说明:https://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionViewFlowLayout_class/Reference/Reference.html#//apple_ref/occ/cl/UICollectionViewFlowLayout,进一步定制可参考官方这个文档:https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/UsingtheFlowLayout/UsingtheFlowLayout.html#//apple_ref/doc/uid/TP40012334-CH3-SW4

Cells和其它View

collection view管理者cells,supplementary views和decoration views

  • cells:和tableview的cell类似。
  • Supplementary views:相当于tableview的section header和footer views,不同的是数量和位置由布局控制
  • Decoration views:装饰用

基于内容的布局计算自定义布局

子类重写的方法可以参考官方文档:https://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionViewLayout_class/Reference/Reference.html

collectionViewContentSize

- (CGSize)collectionViewContentSize
{
     //不能水平滚动
     CGFloat contentWidth = self.collectionView.bounds.size.width;

     //垂直滚动显示完整数据
     CGFloat contentHeight = DayHeaderHeight + (HeightPerHour * HoursPerDay);

     CGSize contentSize = CGSizeMake(contentWidth, contentHeight);
     return contentSize;
}

布局中最重要的方法layoutAttributesForElementsInRect:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
     NSMutableArray *layoutAttributes = [NSMutableArray array];
     // Cells
     // We call a custom helper method -indexPathsOfItemsInRect: here
     // which computes the index paths of the cells that should be included
     // in rect.
     NSArray *visibleIndexPaths = [self indexPathsOfItemsInRect:rect];
     for (NSIndexPath *indexPath in visibleIndexPaths) {
          UICollectionViewLayoutAttributes *attributes =
          [self layoutAttributesForItemAtIndexPath:indexPath];
          [layoutAttributes addObject:attributes];
     }

     // Supplementary views
     NSArray *dayHeaderViewIndexPaths = [self indexPathsOfDayHeaderViewsInRect:rect];
     for (NSIndexPath *indexPath in dayHeaderViewIndexPaths) {
          UICollectionViewLayoutAttributes *attributes =
          [self layoutAttributesForSupplementaryViewOfKind:@“DayHeaderView" atIndexPath:indexPath];
     [layoutAttributes addObject:attributes];
     }

     NSArray *hourHeaderViewIndexPaths = [self indexPathsOfHourHeaderViewsInRect:rect];
     for (NSIndexPath *indexPath in hourHeaderViewIndexPaths) {
          UICollectionViewLayoutAttributes *attributes =
          [self layoutAttributesForSupplementaryViewOfKind:@"HourHeaderView"
atIndexPath:indexPath];
          [layoutAttributes addObject:attributes];
     }
     return layoutAttributes;
}

layoutAttributesForItemAtIndexPath:

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
     CalendarDataSource *dataSource = self.collectionView.dataSource;
     id event = [dataSource eventAtIndexPath:indexPath];
     UICollectionViewLayoutAttributes *attributes =
     [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
     attributes.frame = [self frameForEvent:event];
     return attributes;
}

shouldInvalidateLayoutForBoundsChange:

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
     CGRect oldBounds = self.collectionView.bounds;
     if (CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds)) {
          return YES;
     }
     return NO;
}

插入,删除和布局间切换的动画

插入,删除

  • initialLayoutAttributesForAppearingItemAtIndexPath:
  • initialLayoutAttributesForAppearingSupplementaryElementOfKind:atIndexPath:
  • initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath:
  • finalLayoutAttributesForDisappearingItemAtIndexPath:
  • finalLayoutAttributesForDisappearingSupplementaryElementOfKind:atIndexPath:
  • finalLayoutAttributesForDisappearingDecorationElementOfKind:atIndexPath: 发送setCollectionViewLayout:animated:消息,collection view会为cells在新布局参数,动态将每个cell从旧变到新。

范例