我们很多iOS开发者应该都用过autolayout ,如果用故事版和XIB的话非常好用,但是如果用纯代码的方式写的话就感觉这东西太啰嗦了,一点都不好用,还不如frame来得快,然而在公司项目中一般都是多人开发,因此还是以纯代码写的方式比较多;随着苹果大屏手机的推出,autolayout越来越势在必行了,然而我们却发现这东西以代码写的方式简直可以让人写到吐血,还好一个国外大神推出了一套封装好autolayout框架Masnory, Masonry是一个轻量级的布局框架拥有自己的描述语法采用更优雅的链式语法封装自动布局简洁明了并具有高可读性而且同时支持iOS和Max OS X。(示例代码下载地址)
Masonry框架怎么学习我这里就不详细说了,网上一大堆,都很不错;使用Masonry很好用可以布局任何我们想要的结果,但是在计算cell高度方面确实遇到了一些小麻烦,我在网上找了很多资料,都不是很理想,我记得其中一个Masonry+FF什么的框架来计算cell高度,我擦好麻烦,我想不用这么啰嗦吧!于是乎自己搞了一个下午,搞出了一套简单的方法,供大家参考学习。交流群 519797474
效果图如下:
废话不多话 直接上代码
[objc]view plaincopy
#import "HomeViewController.h"
#import "HomeViewCell.h"
#import "HomeModel.h"
@interfaceHomeViewController ()
@property(nonatomic,strong)NSMutableArray*arr;//存放的我们自定义的数据
@property(nonatomic,strong)NSMutableArray*arrModel;//存放的数据模型
@end
@implementationHomeViewController
//存放我们自己定义的数据 并转成模型 然后把模型存到arrModel数组中
-(NSMutableArray*)arr
{
if(_arr==nil){
_arr=[NSMutableArrayarray];
[_arraddObject:@"高通与小米达成专利授权协议的主要影响在于小米的海外市场,因为在国内小米并不会遇到专利问题。然而,分析小米在海外遇到的问题会发现,这远不是签订一个专利协议能解决"];
[_arraddObject:@"当年科比和乔丹的对决,那时的科比几乎无所不能,谁又会想到他会退役,说不定再过10年,我也就退役了。"];
[_arraddObject:@"高通与小米达成专利授权协议的主要影响在于小米的海外市场,因为在国内小米并不会遇到专利问题。然而,分析小米在海外遇到的问题会发现,这远不是签订一个专利协议能解决"];
[_arraddObject:@"hello 这是我的iOS学习群 519797474,欢迎加入"];
[_arraddObject:@"佛堂中,大师正在对弟子讲话:“为师为你们所起之名并非随随便便,而是为师对你们的期望,你们懂了吗?”众弟子都回答懂了。只有一名弟子默然不语。大师见状,问那名弟子道:“圆寂,你为什么不说话?"];
[_arraddObject:@"最后这个例子是老例子了最后这个例子是老例子了,我想给大家看看其实Masonry做动画也和其他的Autolayout方法一样,但是添加约束的代码却非常的少最后这个例子是老例子了,我想给大家看看其实Masonry做动画也和其他的Autolayout方法一样,但是添加约束的代码却非常的少最后这个例子是老例子了,我想给大家看看其实Masonry做动画也和其他的Autolayout方法一样,但是添加约束的代码却非常的少最后这个例子是老例子了,我想给大家看看其实Masonry做动画也和其他的Autolayout方法一样,但是添加约束的代码却非常的少最后这个例子是老例子了,我想给大家看看其实Masonry做动画也和其他的Autolayout方法一样,但是添加约束的代码却非常的少最后这个例子是老例子了,我想给大家看看其实Masonry做动画也和其他的Autolayout方法一样,但是添加约束的代码却非常的少"];
[_arraddObject:@"今天和老婆吵架,吵到激烈的时候,我突然觉得我一个大男人为什么要和一个女人一般见识呢?何况还是自己的老婆!当时我就跟老婆道了歉,老婆挺高兴的.道完歉,她哥哥把菜刀放下了,她弟弟把铁锹也放下了,她妹妹拽着我头发的手也松开了,妹夫手里的擀面杖也扔地下了,老丈人也把砖头丢开了;"];
[_arraddObject:@"昨天去一家工厂面试监工,给出的工资太低,简直不能忍。最后跟主管去车间看了看,我觉得工资只是数字而已,关键是学习的机会,所以留下来了。"];
[_arraddObject:@"大家好,我是他主治医生。请原谅他,他因为神经病引起的并发症迷恋上了装逼,去年高考 ,他差一点就上清华了,现在想来依然倍感惋惜,清华分数695,他考了69.5,就差那么一点。巨大的打击彻底粉碎了他对未来的憧憬,整日在家自暴自弃专研怎么装逼,终成为新一代装逼大师,将装逼 方法研究的出神入化,各种装逼方法,无死角装逼,终于横空出世…。你看,他又在装逼......."];
[_arraddObject:@"高通与小米达成专利授权协议的主要影响在于小米的海外市场,因为在国内小米并不会遇到专利问题。然而,分析小米在海外遇到的问题会发现,这远不是签订一个专利协议能解决,周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工周鸿祎的当别人都这么做的时候,我们换一种方式去做;和雷军的打败一种东西的一定是更新的东西而不是简单的复制。越想越觉得他们的理念异曲同工"];
[_arraddObject:@"很多时候我们过高估计了机遇的力量,低估了规划的重要性,不明确的乐观主义者只知道未来越来越好,却不知道究竟多好,因此不去制定具体计划。他想在未来获利,但是却认为没有必要制定具体规划。"];
[_arraddObject:@"hello 这是我的iOS学习群 519797474,欢迎加入"];
for(inti=0;i<_arr.count;i++){
HomeModel*m=[[HomeModelalloc]init];
m.icon=[NSStringstringWithFormat:@"%i",i];
m.content=_arr[i];
//把模型那存到模型数组中
[self.arrModeladdObject:m];
}
}
return_arr;
}
//存放模型的数组
-(NSMutableArray*)arrModel
{
if(_arrModel==nil){
_arrModel=[NSMutableArrayarray];
}
return_arrModel;
}
- (void)viewDidLoad {
[superviewDidLoad];
self.tableView.separatorStyle=UITableViewCellSeparatorStyleNone;//去掉默认下划线
self.tableView.estimatedRowHeight=200;//预估行高 可以提高性能
self.tableView.rowHeight=88;
//注册表格单元
[self.tableViewregisterClass:[HomeViewCellclass]forCellReuseIdentifier:homeIndentifier];
}
/*
返回多少行
*/
- (NSInteger)tableView:(UITableView*)tableViewnumberOfRowsInSection:(NSInteger)section {
//因为是我们自定义的数据 所以 这里写arr而不是arrModel 因为只有这样才会调用arr的懒加载犯法
returnself.arr.count;
}
/*
返回表格单元
*/
- (UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath {
//取出模型
HomeModel*model=self.arrModel[indexPath.row];
HomeViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:homeIndentifier];
//传递模型给cell
cell.homeModel=model;
returncell;
}
/*
* 返回每一个表格单元的高度
*/
-(CGFloat)tableView:(UITableView*)tableViewheightForRowAtIndexPath:(NSIndexPath*)indexPath
{
//取出模型
HomeModel*homeModel=self.arrModel[indexPath.row];
//这个方法会调用模型里面对应的cell,cell再去调用他本身计算cell高度的方法
returnhomeModel.cellHeight;
}
@end
下面是表格cell的代码 (视图类)
[objc]view plaincopy
#import
#import "Masonry.h"
@classHomeModel;
staticNSString*homeIndentifier=@"homeCell";
@interfaceHomeViewCell : UITableViewCell
//数据模型
@property(nonatomic,strong)HomeModel*homeModel;
//我们最后得到cell的高度的方法
-(CGFloat)rowHeightWithCellModel:(HomeModel*)homeModel;
@end
#import "HomeViewCell.h"
#import "HomeModel.h"
//头像的高度
#define iconH 80
#define iconW 100
//间距
#define marginW 10
@interfaceHomeViewCell ()
@property(nonatomic,weak)UIImageView*icon;//头像
@property(nonatomic,weak)UILabel*content;//显示文本的label
@property(nonatomic,weak)UIImageView*line;//下划线
//定义一个contentLabel文本高度的属性
@property(nonatomic,assign) CGFloat contentLabelH;
@end
@implementationHomeViewCell
-(instancetype)initWithStyle:(UITableViewCellStyle)stylereuseIdentifier:(NSString*)reuseIdentifier
{
self=[superinitWithStyle:stylereuseIdentifier:reuseIdentifier];
if(self){
//1.添加子控件
[selfsetupUI];
}
returnself;
}
#pragma mark 添加子控件
-(void)setupUI
{
//1.添加图片
UIImageView*icon=[UIImageViewnew];
icon.contentMode=UIViewContentModeScaleAspectFill;
icon.clipsToBounds=YES;
[self.contentViewaddSubview:icon];
self.icon=icon;
//2.添加label
UILabel*content=[UILabelnew];
content.numberOfLines=0;//多行显示
content.font=[UIFontsystemFontOfSize:16];
[self.contentViewaddSubview:content];
self.content=content;
//3.底部添加一条线
UIImageView*line=[UIImageViewnew];
line.backgroundColor=[UIColorgrayColor];
[self.contentViewaddSubview:line];
self.line=line;
//设置约束
__weak __typeof(&*self)weakSelf =self;
//1.设置图片的大小
[self.iconmas_makeConstraints:^(MASConstraintMaker*make) {
make.height.mas_equalTo(iconH);//头像的高度
make.width.mas_equalTo(iconW);//头像的宽度
make.top.equalTo(weakSelf.mas_top).offset(marginW) ;//距离顶部10的距离
make.centerX.equalTo(weakSelf.mas_centerX);//头像的中心x和cell的中心x一样
// make.centerY.equalTo(self.mas_centerY); 头像的中心y和cell的中心y一样
}];
//2.设置contentLabel
[self.contentmas_makeConstraints:^(MASConstraintMaker*make) {
make.top.equalTo(weakSelf.icon.mas_bottom).offset(marginW);//文本距离头像底部10个间距
make.left.equalTo(weakSelf.mas_left).offset(marginW);//文本距离左边的距离
make.right.equalTo(weakSelf.mas_right).offset(-marginW);//文本距离右边的距离
//文本高度 我们再得到模型的时候 在传递
}];
//3.设置下划线的大小
[self.linemas_makeConstraints:^(MASConstraintMaker*make) {
make.height.mas_equalTo(0.5);
make.left.equalTo(weakSelf.mas_left).offset(0);
make.right.equalTo(weakSelf.mas_right).offset(0);
make.bottom.equalTo(weakSelf.mas_bottom).offset(-marginW);//下划线距离底部10的距离
}];
}
//传递数据模型
-(void)setHomeModel:(HomeModel*)homeModel
{
_homeModel=homeModel;
self.icon.image=[UIImageimageNamed:homeModel.icon];//头像
self.content.text=homeModel.content;//文本内容
}
//在表格cell中 计算出高度
-(CGFloat)rowHeightWithCellModel:(HomeModel*)homeModel
{
_homeModel=homeModel;
__weak __typeof(&*self)weakSelf =self;
//设置标签的高度
[self.contentmas_makeConstraints:^(MASConstraintMaker*make) {
// weakSelf.contentLabelH 这个会调用下面的懒加载方法
make.height.mas_equalTo(weakSelf.contentLabelH);
}];
// 2. 更新约束
[selflayoutIfNeeded];
//3. 视图的最大 Y 值
CGFloat h= CGRectGetMaxY(self.content.frame);
returnh+marginW;//最大的高度+10
}
/*
* 懒加载的方法返回contentLabel的高度 (只会调用一次)
*/
-(CGFloat)contentLabelH
{
if(!_contentLabelH){
CGFloat h=[self.homeModel.contentboundingRectWithSize:CGSizeMake(([UIScreenmainScreen].bounds.size.width)-2*marginW, MAXFLOAT)options:NSStringDrawingUsesLineFragmentOriginattributes:@{NSFontAttributeName:[UIFontsystemFontOfSize:16]}context:nil].size.height;
_contentLabelH=h+marginW;//内容距离底部下划线10的距离
}
return_contentLabelH;
}
@end
下面是数据模型 (HomeModel类)
[objc]view plaincopy
#import
@interfaceHomeModel : NSObject
@property(nonatomic,copy)NSString*icon;//图片
@property(nonatomic,copy)NSString*content;//内容的label
//单元格的高度
@property(nonatomic,assign) CGFloat cellHeight;
@end
#import "HomeModel.h"
#import "HomeViewCell.h"
@implementationHomeModel
//惰性初始化是这样写的 只会加载一次,不会造成循环引用的性能问题
-(CGFloat)cellHeight
{
//只在初始化的时候调用一次就Ok
if(!_cellHeight){
HomeViewCell*cell=[[HomeViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:homeIndentifier];
NSLog(@"我要计算高度");
// 调用cell的方法计算出高度
_cellHeight=[cellrowHeightWithCellModel:self];
}
return_cellHeight;
}
@end
到这里我们整个计算cell高度的方法就完了,最重要的是我们要学会举一反三,学会这套思想,从而可以使用autolayout框架写出任何我们想要布局的代码
转载:http://blog.csdn.net/joonchen111/article/details/50193499