0%

UICollectionview

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (CGSize)collectionViewContentSize

{

//不能水平滚动

CGFloat contentWidth = self.collectionView.bounds.size.width;

//垂直滚动显示完整数据

CGFloat contentHeight = DayHeaderHeight + (HeightPerHour * HoursPerDay);

CGSize contentSize = CGSizeMake(contentWidth, contentHeight);

return contentSize;

}

布局中最重要的方法layoutAttributesForElementsInRect:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

- (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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

- (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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

- (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从旧变到新。

范例