上篇文章说明了标准MVC下如何动态生成标准MVC下生成动态生成UICollectionViewCell的size,并且在此部分工作由View完成。连接如下:
标准MVC下生成动态生成UICollectionViewCell的size(View内完成)
这篇文章主要说明的是如何在Controller实现这部分功能。
效果图如下(跟之前没什么区别)
同样自定义UICollectionViewCell:
#import <UIKit/UIKit.h>
@interface LCHCollectionViewCell : UICollectionViewCell
@property (nonatomic, strong) UILabel *firstLabel;
@property (nonatomic, strong) UILabel *secondLabel;
@end
然后重写其initWithFrame方法,用于将label加到其contentView中去:
@implementation LCHCollectionViewCell
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_firstLabel = [[UILabel alloc] init];
_firstLabel.numberOfLines = 1;
_firstLabel.textAlignment = NSTextAlignmentCenter;
_firstLabel.backgroundColor = [UIColor redColor];
_firstLabel.font = [UIFont systemFontOfSize:25];
_secondLabel = [[UILabel alloc] init];
_secondLabel.numberOfLines = 1;
_secondLabel.textAlignment = NSTextAlignmentCenter;
_secondLabel.backgroundColor = [UIColor greenColor];
_secondLabel.font = [UIFont systemFontOfSize:25];
[self.contentView addSubview:_firstLabel];
[self.contentView addSubview:_secondLabel];
self.backgroundColor = [UIColor blackColor];
}
return self;
}
@end
label简单的alloc init之后加到contentView中即可,不用向我这样设置这些属性,毕竟这种方式下C需要知道V的任何细节,所以这些属性应该由C来完成。
接下来在UICollectionViewDelegateFlowLayout协议中
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
的这个方法内,计算并返回当前M数据中所需的V的size (V就是一个容器,M是内容,所以知道内容之后就应该知道容器的大小)。
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
LCHModel *model = self.models[indexPath.row];
CGSize sizeForFirstLabel = [model.firstString boundingRectWithSize:CGSizeMake([[UIScreen mainScreen] bounds].size.width, __FLT_MAX__) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,NSFontAttributeName:[UIFont systemFontOfSize:25]} context:nil].size;
CGSize sizeForSecondLabel = [model.secondString boundingRectWithSize:CGSizeMake([[UIScreen mainScreen] bounds].size.width, __FLT_MAX__) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,NSFontAttributeName:[UIFont systemFontOfSize:25]} context:nil].size;
return CGSizeMake(sizeForFirstLabel.width + sizeForSecondLabel.width, MAX(sizeForFirstLabel.height, sizeForSecondLabel.height));
}
然后在UICollectionViewDataSource的
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
这个方法中,详细设置V的subviews的frame
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
LCHCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"reuse" forIndexPath:indexPath];
LCHModel *model = self.models[indexPath.row];
cell.firstLabel.text = model.firstString;
cell.secondLabel.text = model.secondString;
CGSize sizeForFirstLabel = [model.firstString boundingRectWithSize:CGSizeMake([[UIScreen mainScreen] bounds].size.width, __FLT_MAX__) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,NSFontAttributeName:[UIFont systemFontOfSize:25]} context:nil].size;
CGSize sizeForSecondLabel = [model.secondString boundingRectWithSize:CGSizeMake([[UIScreen mainScreen] bounds].size.width, __FLT_MAX__) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,NSFontAttributeName:[UIFont systemFontOfSize:25]} context:nil].size;
CGRect firstLabelFrame = cell.firstLabel.frame;
CGRect secondLabelFrame = cell.secondLabel.frame;
firstLabelFrame.size = sizeForFirstLabel;
secondLabelFrame.size = sizeForSecondLabel;
secondLabelFrame.origin.x = sizeForFirstLabel.width;
cell.firstLabel.frame = firstLabelFrame;
cell.secondLabel.frame = secondLabelFrame;
return cell;
}
这个Demo的地址如下: