集合视图是iOS 6推出的新视图,克服了表视图中一行只能显示一个单元的缺陷。下面来简单看看怎么使用集合视图,一共有5个步骤,如下:
1.自定义单元
2.配置视图控制器
3.内容单元
4.实现流式布局
5.分区标题视图
接下来,看看每一步的操作。
自定义视图
继承UICollectionViewCell,定义自己的属性
ContentCell.h
```objc
import
@interface ContentCell : UICollectionViewCell
@property (strong, nonatomic) UILabel *label;
@property (copy, nonatomic) NSString *text;
+ (CGSize)sizeForContentString:(NSString *)s;
@end
```
ContentCell.m
```objc
import ContentCell.h
@implementation ContentCell
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.label = [[UILabel alloc] initWithFrame:self.contentView.bounds];
self.label.opaque = NO;
self.label.backgroundColor = [UIColor colorWithRed:0.8 green:0.9 blue:1 alpha:1];
self.label.textColor = [UIColor blackColor];
self.label.textAlignment = NSTextAlignmentCenter;
self.label.font = [[self class] defaultFont];
[self.contentView addSubview:self.label];
}
return self;
} - (UIFont *)defaultFont{
return [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
} - (CGSize)sizeForContentString:(NSString *)s{
CGSize maxSize = CGSizeMake(300, 1000);
NSStringDrawingOptions opts = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineBreakMode:NSLineBreakByWordWrapping];NSDictionary *attributes = @{ NSFontAttributeName:[self defaultFont],
NSParagraphStyleAttributeName:style};
CGRect rect = [s boundingRectWithSize:maxSize options:opts attributes:attributes context:nil];
return rect.size;
} - (NSString *)text{
return self.label.text;
} - (void)setText:(NSString *)text{
self.label.text = text;
CGRect newLabelFrame = self.label.frame;
CGRect newContentFrame = self.contentView.frame;
CGSize textSize = [[self class] sizeForContentString:text];
newLabelFrame.size = textSize;
newContentFrame.size = textSize;
self.label.frame = newLabelFrame;
self.contentView.frame = newContentFrame;
}
@end
```
配置视图控制器
这步跟表视图类似,初始化数据,初始化集合视图,注册Cell
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = NO;
self.sections =
@[
@{ @"header" : @"First Witch",
@"content" : @"Hey, when will the three of us meet up later?" },
@{ @"header" : @"Second Witch",
@"content" : @"When everything's straightened out." },
@{ @"header" : @"Third Witch",
@"content" : @"That'll be just before sunset." },
@{ @"header" : @"First Witch",
@"content" : @"Where?" },
@{ @"header" : @"Second Witch",
@"content" : @"The dirt patch." },
@{ @"header" : @"Third Witch",
@"content" : @"I guess we'll see Mac there." },
];
// Register cell classes
[self.collectionView registerClass:[ContentCell class] forCellWithReuseIdentifier:@"CONTENT"];
[self.collectionView registerClass:[HeaderCell class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HEADER"];
// Do any additional setup after loading the view.
self.collectionView.backgroundColor = [UIColor whiteColor];
UIEdgeInsets contentInset = self.collectionView.contentInset;
contentInset.top = 20;
[self.collectionView setContentInset:contentInset];
//流式布局时会用到
UICollectionViewLayout *layout = self.collectionView.collectionViewLayout;
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)layout;
flow.sectionInset = UIEdgeInsetsMake(10, 20, 30, 20);
flow.headerReferenceSize = CGSizeMake(100, 25);
}
内容单元
可以发现,到这一步为止,都跟表视图的操作类似
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return self.sections.count;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
NSArray *words = [self wordsInSection:section];
return words.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSArray *words = [self wordsInSection:indexPath.section];
ContentCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CONTENT" forIndexPath:indexPath];
cell.text = words[indexPath.row];
// Configure the cell
return cell;
}
实现流式布局
这里定义了每个单元的大小。
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
NSArray *words = [self wordsInSection:indexPath.section];
CGSize size = [ContentCell sizeForContentString:words[indexPath.row]];
return size;
}
以下代码放在viewDidLoad中,用来控制单元之间的距离。
//流式布局时会用到
UICollectionViewLayout *layout = self.collectionView.collectionViewLayout;
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)layout;
flow.sectionInset = UIEdgeInsetsMake(10, 20, 30, 20);
分区标题视图
我们可以定义集合视图的分区标题视图,实现更多的效果。
首先得定义一个Cell
HeaderCell.m
```objc
import HeaderCell.h
@implementation HeaderCell
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.label.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.8 alpha:1];
self.label.textColor = [UIColor blackColor];
}
return self;
} - (UIFont *)defaultFont{
return [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
}
@end
```
再使用以下代码进行设置。
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
if ([kind isEqual:UICollectionElementKindSectionHeader]) {
HeaderCell *cell = [self.collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"HEADER" forIndexPath:indexPath];
cell.text = self.sections[indexPath.section][@"header"];
return cell;
}
return nil;
}
另外,还需要在初始化时注册cell以及显示指定大小
//注册headerCell
[self.collectionView registerClass:[HeaderCell class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HEADER"];
UICollectionViewLayout *layout = self.collectionView.collectionViewLayout;
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)layout;
flow.sectionInset = UIEdgeInsetsMake(10, 20, 30, 20);
//指定header的大小
flow.headerReferenceSize = CGSizeMake(100, 25);