学习UICollectionView笔记
UICollectionViewCell
值得注意的是,它使用defaultFont类方法获取字体,然后设置字体。这么做的原因是类需要使用这个方法确定显示内容所使用的字体,同时也可以让任何子类通过override defaultFont方法定义各自用于显示的字体.
+ (UIFont *)defaultFont{
return [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
}
...
self.label.font = [[self class] defaultFont];
如果是xib或者纯代码写的cell,那么就要register。如果是在storyboard中设计的,那么就不必register了。
如果一个应用没有导航栏(就是没有放在nav容器中),主视图依然会影响到状态栏status bar。在viewDidLoad方法的末尾添加以下代码就能防止这种状况:
UIEdgeInsets contentInset = self.collectionView.contentInset;
contentInset.top = 10;
self.collectionView.contentInset = contentInset;
用whiteSpace和newLine分隔一长串字符串,返回一个包含所有被分割的单词的数组:
- (NSArray *)wordsInsection:(NSInteger)section{
NSString *content = self.sections[section][@"content"];
NSCharacterSet *space = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSArray *words = [content componentsSeparatedByCharactersInSet:space];
return words;
}
由于两个cell类(headerCell ContentCell)有相同的功能,所以我们让一个继承另一个,并override部分功能。需要被override的部分,单独写作一个方法。
NSArray作为属性,用copy语义
代码中自定义cell时,首先要在initWithFrame:方法里面构建好cell内部的控件及其位置。
cell中定义一个类方法,用来计算给定字符串所需size:(其中设定了最大size,以免内容显示不全
+ (CGSize)sizeForContentString:(NSString *)string {
CGSize maxSize = CGSizeMake(300, 1000);
NSStringDrawingOptions opts = NSStringDrawingUsesLineFragmentOrigin |
NSStringDrawingUsesFontLeading;
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineBreakMode:NSLineBreakByCharWrapping];
NSDictionary *attributes = @{ NSFontAttributeName : [self defaultFont],
NSParagraphStyleAttributeName : style };
CGRect rect = [string boundingRectWithSize:maxSize
options:opts
attributes:attributes
context:nil];
return rect.size;
}
重写text属性的setter和getter,作用如下:
- 外部配置该cell时,可以十分直观地配置该cell的text属性,在内部会将这个需要配置的字符串赋值给label,同时调整字符串所需的size。注意,frame只能整体调整,所以先获取并保存原来的frame,改变size后,再赋值给原frame.
- 外部读取text时,可以通过label获取需要的内容。
- (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;
}
CollectionView的dataSource和flowDelegate配置
一般用一个sections数组,包含多个字典,每个字典中保存每个cell内部内容.
UICollectionView默认为黑色背景,调为白色好看。
UICollectionView 的 flow layout delegate基本方法
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
用以提供每个item的size
以下代码首先从集合视图得到布局对象。首先使用一个临时的UICollectionViewLayout对象来保存这个布局对象,这主要是突出一个点:UICollectionView仅仅好像是“知道”布局类的大致情况,但并不能在runtime直接使用它。在实践中,除非特别指定,否则我们都是使用UICollectionFlowLayout实例处理布局。由于知道布局对象的真正类型,所以可以使用类型转换将其赋值给另一个变量,这样就可以访问相应地布局对象子类的方法了.
// flow config
UICollectionViewLayout *layout = self.collectionView.collectionViewLayout;
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)layout;
flow.sectionInset = UIEdgeInsetsMake(10, 20, 30, 20);
对于headerView,先要register forSupplementaryViewOfKind并给定reuseIdentifier
指定之后完成特定的委托方法:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath{
BIDHeaderCell *cell = [self.collectionView
dequeueReusableSupplementaryViewOfKind:kind
withReuseIdentifier:@"HEADER"
forIndexPath:indexPath];
cell.text = self.sections[indexPath.section][@"header"];
return cell;
}
cell的headerView的复用方法
且要有:
if ([kind isEqual:UICollectionElementKindSectionHeader])
除非明确指定headerView的尺寸,否则UICollectionFlowLayout不会为headerView提供任何显示空间,所以在viewDidLoad中添加如下方法:
flow.headerReferenceSize = CGSizeMake(100, 25);
网友评论